instrument.dhover×51all
// instrument.d — shared stderr instrumentation for the windowing feature demos.
//
// Implements the log contract from the F01 spec
// (../../../features/f01-first-pixel.md): one line per event, formatted as
//
//     <monotonic_us> <DEMO> <EVENT_KIND> key=value ...
//
// where <monotonic_us> is microseconds since instrumentInit() measured with
// core.time.MonoTime (a monotonic clock, so wall-clock jumps cannot corrupt
// deltas). Every fXX feature demo copies this file verbatim from the scaffold.
//
// Deliberately @nogc + nothrow: it must be callable from an extern(Windows)
// WndProc (which may not let a D exception unwind into OS code) and must not
// perturb the timings it measures with GC pauses.
module 
(module) instrument
instrument
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdarg

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html, stdarg.h

Source

core/stdc/stdarg.d

@copyrightCopyright Digital Mars 2000 - 2020.@licenseBoost License 1.0.@authorsWalter Bright, Hauke Duden@standardsISO/IEC 9899:1999 (E)
stdarg
:
(alias template) instrument.va_end = core.stdc.stdarg.va_end()(va_list ap)

End use of ap.

va_end
, va_list,
(alias template) instrument.va_start = core.stdc.stdarg.va_start(T)(out va_list ap, ref T parmn)

Initialize ap. parmn should be the last named parameter.

va_start
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdio

D header file for C99 <stdio.h>

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h

Source

core/stdc/stdio.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
stdio
:
(alias) instrument.fflush = int core.stdc.stdio.fflush(shared(core.stdc.stdio._IO_FILE)* stream) nothrow @nogc @trusted
fflush
,
(alias) instrument.fprintf = int core.stdc.stdio.fprintf(shared(core.stdc.stdio._IO_FILE)* stream, scope const(char*) format, scope const ...) nothrow @nogc
fprintf
,
(alias shared global) instrument.stderr = shared(core.stdc.stdio._IO_FILE*) core.stdc.stdio.stderr
stderr
,
(alias) instrument.vfprintf = int core.stdc.stdio.vfprintf(shared(core.stdc.stdio._IO_FILE)* stream, scope const(char*) format, core.internal.vararg.sysv_x64.__va_list_tag* arg) nothrow @nogc
vfprintf
;
import
(package) core
core
.
(module) core.time

Module containing core time functionality, such as Duration (which represents a duration of time) or MonoTime (which represents a timestamp of the system's monotonic clock).

Various functions take a string (or strings) to represent a unit of time (e.g. convert!("days", "hours")(numDays)). The valid strings to use with such functions are "years", "months", "weeks", "days", "hours", "minutes", "seconds", "msecs" (milliseconds), "usecs" (microseconds), "hnsecs" (hecto-nanoseconds - i.e. 100 ns) or some subset thereof. There are a few functions that also allow "nsecs", but very little actually has precision greater than hnsecs.

Symbol Description
Types
Duration Represents a duration of time of weeks or less (kept internally as hnsecs). (e.g. 22 days or 700 seconds).
TickDuration DEPRECATED Represents a duration of time in system clock ticks, using the highest precision that the system provides.
MonoTime Represents a monotonic timestamp in system clock ticks, using the highest precision that the system provides.
Functions
convert Generic way of converting between two time units.
dur Allows constructing a Duration from the given time units with the given length.
weeks&nbsp;days&nbsp;hours

minutes&nbsp;seconds&nbsp;msecs

usecs&nbsp;hnsecs&nbsp;nsecs | Convenience aliases for dur. | | abs | Returns the absolute value of a duration. |

From Duration
From TickDuration
From units
To Duration
tickDuration.to, std,conv!Duration()
dur!"msecs"(5) or 5.msecs()

| To TickDuration | duration.to, std,conv!TickDuration() |

  • | TickDuration.from!"msecs"(msecs) |

| To units | duration.total!"days" | tickDuration.msecs | convert!("days", "msecs")(msecs) |

Source

core/time.d

@copyrightCopyright 2010 - 2012@licenseBoost License 1.0.@authorsJonathan M Davis and Kato Shoichi
time
:
(struct) core.time.MonoTimeImpl!(ClockType.normal)
MonoTime
;
private __gshared
(struct) core.time.MonoTimeImpl!(ClockType.normal)
MonoTime
(__gshared global) core.time.MonoTimeImpl!(ClockType.normal) instrument.startTime
startTime
;
private __gshared const(char)*
(__gshared global) const(char)* instrument.demoName
demoName
= "demo";
/// Start the monotonic clock and set the `<DEMO>` field of every log line. void
void instrument.instrumentInit(const(char)* name) nothrow @nogc

Start the monotonic clock and set the <DEMO> field of every log line.

instrumentInit
(const(char)*
(parameter) const(char)* name
name
) nothrow @nogc
{
(__gshared global) core.time.MonoTimeImpl!(ClockType.normal) instrument.startTime
startTime
=
(struct) core.time.MonoTimeImpl!(ClockType.normal)
MonoTime
.
core.time.MonoTimeImpl!(ClockType.normal) core.time.MonoTimeImpl!(ClockType.normal).currTime() nothrow @nogc @property @trusted

The current time of the system's monotonic clock. This has no relation to the wall clock time, as the wall clock time can be adjusted (e.g. by NTP), whereas the monotonic clock always moves forward. The source of the monotonic time is system-specific.

On Windows, QueryPerformanceCounter is used. On Mac OS X, mach_absolute_time is used, while on other POSIX systems, clock_gettime is used.

Warning: On some systems, the monotonic clock may stop counting when the computer goes to sleep or hibernates. So, the monotonic clock may indicate less time than has actually passed if that occurs. This is known to happen on Mac OS X. It has not been tested whether it occurs on either Windows or Linux.

currTime
;
(__gshared global) const(char)* instrument.demoName
demoName
=
(parameter) const(char)* name
name
;
} /// Microseconds elapsed since `instrumentInit`. long
long instrument.nowUs() nothrow @nogc

Microseconds elapsed since instrumentInit.

nowUs
() nothrow @nogc
{ return (
(struct) core.time.MonoTimeImpl!(ClockType.normal)
MonoTime
.
core.time.MonoTimeImpl!(ClockType.normal) core.time.MonoTimeImpl!(ClockType.normal).currTime() nothrow @nogc @property @trusted

The current time of the system's monotonic clock. This has no relation to the wall clock time, as the wall clock time can be adjusted (e.g. by NTP), whereas the monotonic clock always moves forward. The source of the monotonic time is system-specific.

On Windows, QueryPerformanceCounter is used. On Mac OS X, mach_absolute_time is used, while on other POSIX systems, clock_gettime is used.

Warning: On some systems, the monotonic clock may stop counting when the computer goes to sleep or hibernates. So, the monotonic clock may indicate less time than has actually passed if that occurs. This is known to happen on Mac OS X. It has not been tested whether it occurs on either Windows or Linux.

currTime
-
core.time.Duration core.time.MonoTimeImpl!(ClockType.normal).opBinary!"-"(core.time.MonoTimeImpl!(ClockType.normal) rhs) const pure nothrow @nogc @safe

Subtracting two MonoTimes results in a Duration representing the amount of time which elapsed between them.

The primary way that programs should time how long something takes is to do

MonoTime before = MonoTime.currTime;
// do stuff
MonoTime after = MonoTime.currTime;

// How long it took.
Duration timeElapsed = after - before;

or to use a wrapper (such as a stop watch type) which does that.

Warning: Because Duration is in hnsecs, whereas MonoTime is in system ticks, it's usually the case that this assertion will fail

auto before = MonoTime.currTime;
// do stuff
auto after = MonoTime.currTime;
auto timeElapsed = after - before;
assert(before + timeElapsed == after);

This is generally fine, and by its very nature, converting from system ticks to any type of seconds (hnsecs, nsecs, etc.) will introduce rounding errors, but if code needs to avoid any of the small rounding errors introduced by conversion, then it needs to use MonoTime's ticks property and keep all calculations in ticks rather than using Duration.

startTime
).
long core.time.Duration.total!"usecs"() const pure nothrow @nogc @property @safe

Returns the total number of the given units in this Duration. So, unlike split, it does not strip out the larger units.

Examples

assert(dur!"weeks"(12).total!"weeks" == 12);
assert(dur!"weeks"(12).total!"days" == 84);

assert(dur!"days"(13).total!"weeks" == 1);
assert(dur!"days"(13).total!"days" == 13);

assert(dur!"hours"(49).total!"days" == 2);
assert(dur!"hours"(49).total!"hours" == 49);

assert(dur!"nsecs"(2007).total!"hnsecs" == 20);
assert(dur!"nsecs"(2007).total!"nsecs" == 2000);
total
!"usecs";
} /// Log one event line: `<monotonic_us> <DEMO> ` + the printf expansion of /// `fmt`, which starts with the EVENT_KIND followed by `key=value` pairs, /// e.g. `logEvent("resize size=%dx%d scale=%d.%02d", w, h, si, sf)`. extern (C) pragma(printf) void
void instrument.logEvent(const(char)* fmt, ...) nothrow @nogc

Log one event line: <monotonic_us> <DEMO> + the printf expansion of fmt, which starts with the EVENT_KIND followed by key=value pairs, e.g. ``logEvent("resize size=%dx%d scale=%d.%02d", w, h, si, sf).

logEvent
(const(char)*
(parameter) const(char)* fmt
fmt
, ...) nothrow @nogc
{
int core.stdc.stdio.fprintf(shared(core.stdc.stdio._IO_FILE)* stream, scope const(char*) format, scope const ...) nothrow @nogc
fprintf
(
(shared global) shared(core.stdc.stdio._IO_FILE*) core.stdc.stdio.stderr
stderr
, "%lld %s ",
long instrument.nowUs() nothrow @nogc

Microseconds elapsed since instrumentInit.

nowUs
(),
(__gshared global) const(char)* instrument.demoName
demoName
);
va_list
(local variable) core.internal.vararg.sysv_x64.__va_list_tag* args
args
;
void core.stdc.stdarg.va_start!(const(char)*)(out core.internal.vararg.sysv_x64.__va_list_tag* ap, ref const(char)* parmn) nothrow @nogc

Initialize ap. parmn should be the last named parameter.

va_start
(
(local variable) core.internal.vararg.sysv_x64.__va_list_tag* args
args
,
(parameter) const(char)* fmt
fmt
);
int core.stdc.stdio.vfprintf(shared(core.stdc.stdio._IO_FILE)* stream, scope const(char*) format, core.internal.vararg.sysv_x64.__va_list_tag* arg) nothrow @nogc
vfprintf
(
(shared global) shared(core.stdc.stdio._IO_FILE*) core.stdc.stdio.stderr
stderr
,
(parameter) const(char)* fmt
fmt
,
(local variable) core.internal.vararg.sysv_x64.__va_list_tag* args
args
);
void core.stdc.stdarg.va_end!()(core.internal.vararg.sysv_x64.__va_list_tag* ap) pure nothrow @nogc @safe

End use of ap.

va_end
(
(local variable) core.internal.vararg.sysv_x64.__va_list_tag* args
args
);
int core.stdc.stdio.fprintf(shared(core.stdc.stdio._IO_FILE)* stream, scope const(char*) format, scope const ...) nothrow @nogc
fprintf
(
(shared global) shared(core.stdc.stdio._IO_FILE*) core.stdc.stdio.stderr
stderr
, "\n");
int core.stdc.stdio.fflush(shared(core.stdc.stdio._IO_FILE)* stream) nothrow @nogc @trusted
fflush
(
(shared global) shared(core.stdc.stdio._IO_FILE*) core.stdc.stdio.stderr
stderr
); // demos can die mid-pump; never lose the tail of the log
}