5. Fast high-resolution clock

5.1. Introduction

.intro: This is the design of the clock module, which implements a fast high-resolution clock for use by the telemetry system.

.readership: This document is intended for any MPS developer.

5.2. Requirements

.req.monotonic: Successive calls to EVENT_CLOCK() must yield values that are monotonically increasing. (So that comparing the timestamp on two events never gives false positives.)

.req.fast: EVENT_CLOCK() should take very little time; it should not require a system call. (So that programs that use the MPS remain usable when telemetry is turned on.)

.req.high-resolution: Successive calls to EVENT_CLOCK() should yield values that are strictly monotonically increasing (so that sorting the telemetry stream puts the events in the order they happened).

5.3. Interface

EventClock

.if.type: The type of timestamps. It must be an unsigned 64-bit integral type, for example a typedef for uint64_t or unsigned __int64.

EVENT_CLOCK_MAKE(lvalue, low, high)

.if.make: Construct an EventClock timestamp from its two halves. The first parameter is an lvalue with type EventClock, and the second and third parameters are 32-bit unsigned integers. The macro must assign a timestamp to lvalue with the value (high << 32) + low.

EVENT_CLOCK(lvalue)

.if.get: Assign an EventClock timestamp for the current time to lvalue, which is an lvalue with type EventClock.

EVENT_CLOCK_PRINT(FILE *stream, EventClock clock)

.if.print: Write the value of clock to the standard C output file handle stream as 16 hexadecimal digits (with leading zeros, and capital letters A to F).

EVENT_CLOCK_WRITE(mps_lib_FILE *stream, EventClock clock)

.if.write: Write the value of clock to the output stream stream as 16 hexadecimal digits (with leading zeros, and capital letters A to F). The macro should be implemented using WriteF().

5.4. Implementation

.impl.tsc: On IA-32 and x86-64, the Time Stamp Counter returned by the RDTSC instruction is a suitable clock for single-core CPUs, but on multiple-core CPUs, different cores may have different values or tick at different speeds, and so it may fail to meet .req.monotonic.