1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- (**
- AUTHOR: Alexey Morozov
- PURPOSE: high precision timer support for Unix platforms
- *)
- MODULE PrecisionTimer;
- IMPORT
- Unix, KernelLog;
- TYPE
- Counter* = HUGEINT; (** Timer counter value type *)
- CONST
- (*
- The IDs of the various system clocks (for POSIX.1b interval timers):
- *)
- CLOCK_REALTIME = 0;
- CLOCK_MONOTONIC = 1;
- CLOCK_PROCESS_CPUTIME_ID = 2;
- CLOCK_THREAD_CPUTIME_ID = 3;
- CLOCK_MONOTONIC_RAW = 4;
- CLOCK_REALTIME_COARSE = 5;
- CLOCK_MONOTONIC_COARSE = 6;
- CLOCK_BOOTTIME = 7;
- CLOCK_REALTIME_ALARM = 8;
- CLOCK_BOOTTIME_ALARM = 9;
- TYPE
- Timespec = RECORD
- sec: LONGWORD;
- nsec: LONGINT;
- END;
- VAR
- clock_gettime: PROCEDURE{C}(clk_id: LONGINT; CONST tp: Timespec): LONGINT;
- clock_getres: PROCEDURE{C}(clk_id: LONGINT; CONST res: Timespec): LONGINT;
- (*! It is preferable to use CLOCK_MONOTONIC_RAW (not influenced by system time adjustments),
- but for some reason CLOCK_MONOTONIC is ~3 times faster
- *)
- clockType := CLOCK_MONOTONIC: LONGINT; (* timer clock type *)
- frequency: Counter; (* timer frequency in Hz *)
- (**
- Query timer counter in ticks
- *)
- PROCEDURE GetCounter*(): Counter;
- VAR t: Timespec;
- BEGIN
- IF clock_gettime(clockType, t) = 0 THEN
- RETURN HUGEINT(t.sec)*1000000000 + HUGEINT(t.nsec);
- ELSE
- RETURN 0;
- END;
- END GetCounter;
- (**
- Query timer tick frequency in Hz
- *)
- PROCEDURE GetFrequency*(): Counter;
- VAR t: Timespec;
- BEGIN
- IF clock_getres(clockType, t) = 0 THEN
- (*! a workaround for not known actual clock frequency *)
- RETURN ENTIERH(1.0D9 / t.nsec + 0.5D0);
- ELSE
- RETURN 0;
- END;
- END GetFrequency;
- PROCEDURE InitMod;
- VAR frequency: Counter;
- BEGIN
- Unix.Dlsym(Unix.libc, "clock_gettime", ADDRESSOF(clock_gettime));
- ASSERT(clock_gettime # NIL);
- Unix.Dlsym(Unix.libc, "clock_getres", ADDRESSOF(clock_getres));
- ASSERT(clock_getres # NIL);
- KernelLog.String("PrecisionTimer: timer tick frequency is "); KernelLog.Int(GetFrequency(),0); KernelLog.String(" Hz"); KernelLog.Ln;
- END InitMod;
- BEGIN
- InitMod;
- END PrecisionTimer.
- SystemTools.Free PrecisionTimer ~
|