Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

common-dylan/timers.dylan: new function microsecond-counter #1626

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sources/common-dylan/library.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ define module simple-timers
timer-start,
timer-stop,
timer-accumulated-time,
timer-running?;
timer-running?,
microsecond-counter;
end module simple-timers;

define module byte-vector
Expand Down
1 change: 1 addition & 0 deletions sources/common-dylan/tests/common-dylan-test-suite.lid
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Files: library
streams
byte-vector
machine-words
timers-tests
transcendentals
regressions
threads/simple-locks
Expand Down
1 change: 1 addition & 0 deletions sources/common-dylan/tests/library.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ define module common-dylan-test-suite
use simple-format;
use simple-random;
use simple-profiling;
use simple-timers;
use file-system,
import: { file-exists? };
use operating-system,
Expand Down
14 changes: 14 additions & 0 deletions sources/common-dylan/tests/timers-tests.dylan
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Module: common-dylan-test-suite


define test test-microsecond-counter ()
let t1 = microsecond-counter();
sleep(0.1);
let t2 = microsecond-counter();
let diff = t2 - t1;
// I need slop to be at least 5200 on my macOS M3 Pro. Be more generous than
// that since the main point is simply to exercise the function at all. --cgay
let slop = 50_000;
assert-true(diff >= (100_000 - slop) & diff < (100_000 + slop),
diff);
end test;
15 changes: 15 additions & 0 deletions sources/common-dylan/timers.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,18 @@ define inline function %timer-diff-times
values(seconds, microseconds)
end if
end;

// We use a microsecond counter rather than nanoseconds because implementations
// may legitimately return a time since some arbitrary epoch rather than, say,
// the machine uptime, and that could easily overflow given only 61 usable
// bits. Ex: In 2024, the nanos since 1970-01-01 already uses 61 bits.
define function microsecond-counter () => (microseconds :: <integer>)
let (sec :: <machine-word>, nano :: <machine-word>)
= %timer-current-time();
// I think coerce...(u%-(sec, 0)) is faster than as-unsigned(<integer>, sec)
// due to the latter causing a fully dynamic gf method dispatch. Is there a
// better way?
let seconds :: <integer> = coerce-machine-word-to-integer(u%-(sec, 0));
let microseconds :: <integer> = coerce-machine-word-to-integer(u%divide(nano, 1000));
seconds * 1_000_000 + microseconds
end function;
Loading