feat: time.ticks builtin — CLOCK_MONOTONIC us Int (id 84)
- iteration 22's honest clock: monotone, never wall time; time.now stays ms. One types.ml row, sysio case, explicit dispatch arm (sys range gate stops at PROC_RUN) - corpus run/time-ticks (RED WO-E406 first); oop-e2e 104/0, full battery green; surface doc row (07-systems-stdlib absent, disclosed) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
555a836d90
commit
146d0e27f3
8 changed files with 57 additions and 12 deletions
|
|
@ -290,6 +290,7 @@ let stdlib_members : stdlib_member list =
|
|||
(* time *)
|
||||
m "time" "now" 0 0 (Some (TScalar "Int")) None;
|
||||
m "time" "sleep" 1 46 None None;
|
||||
m "time" "ticks" 0 84 (Some (TScalar "Int")) None;
|
||||
m "time" "local" 1 47 (Some (TScalar time_record_name)) (Some time_record_name);
|
||||
m "time" "iso" 1 48 (Some (TScalar "Text")) None;
|
||||
(* env *)
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ unset `env.get` are nil.
|
|||
| `time.sleep(ms)` | — | |
|
||||
| `time.local(ms)` | `-> TimeParts` | `{ year, month, day, hour, minute, second, dow }`, dow 0 = Sunday |
|
||||
| `time.iso(ms)` | `-> Text` | UTC, second precision |
|
||||
| `time.ticks()` | `-> Int` | CLOCK_MONOTONIC microseconds (id 84, iteration 22's bench clock) — monotone, never wall time; only differences mean anything |
|
||||
| `env.get(name)` | `-> ?Text` | unset is nil |
|
||||
| `env.stopping()` | `-> Bool` | SIGTERM/SIGINT latch, handlers installed on first use |
|
||||
| `net.listen(host, port)` | `-> Int` | IPv4, SO_REUSEADDR, backlog 64; returns an fd |
|
||||
|
|
|
|||
|
|
@ -67,16 +67,16 @@ there). Story:
|
|||
the difference of two calls is a duration). Later tasks time every
|
||||
operation with it.
|
||||
|
||||
- [ ] Corpus fixture first: two `time.ticks()` calls around a spin loop;
|
||||
assert the difference is non-negative and the second call is >= the
|
||||
first (exact values are machine noise — the fixture asserts ordering
|
||||
and that the builtin exists). Verify it FAILS today (unknown builtin).
|
||||
- [ ] Wire the id (84), the sysio case (clock_gettime MONOTONIC,
|
||||
seconds*1e6 + nsec/1e3, as Int), the compiler table rows, the two
|
||||
contract-doc rows (name, arity 0, return Int µs, monotonic-not-wall
|
||||
wording).
|
||||
- [ ] Verify: fixture green under `just oop-e2e`; full battery green.
|
||||
Commit.
|
||||
- [x] Corpus fixture first (`run/time-ticks`): RED as WO-E406, then
|
||||
green — asserts monotonicity + nonzero, values stay machine noise.
|
||||
- [x] Wired: wob.h id 84 + WO_B_MAX bump; the sysio case; ONE compiler
|
||||
table row (types.ml is the single stdlib table — the plan's guess of
|
||||
sibling tables in owner/emit was wrong, no mirror needed); the sys
|
||||
dispatch range needed an explicit `C == WO_B_TIME_TICKS` arm (the
|
||||
range gate stops at PROC_RUN). DEVIATION: `07-systems-stdlib.md`
|
||||
does not exist (a planned doc never written) — the row went into
|
||||
`08-builtin-surface.md` alone.
|
||||
- [x] Verified: oop-e2e 104/0 (was 103); full battery green. Commit.
|
||||
|
||||
## Task 2 — db-bench sample: tables, serial modes, per-op stats
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,8 @@ int wo_builtin(wo_vm *vm, uint64_t *R, uint32_t ins, const char **msg) {
|
|||
both ranges (WO_B_MAP_GET_OPT and anything added after it) stay here */
|
||||
if (C == WO_B_JSON_ENCODE || C == WO_B_JSON_DECODE)
|
||||
return wo_builtin_json(vm, R, ins, msg);
|
||||
if (C >= WO_B_SYS_FIRST && C <= WO_B_PROC_RUN) return wo_builtin_sys(vm, R, ins, msg);
|
||||
if ((C >= WO_B_SYS_FIRST && C <= WO_B_PROC_RUN) || C == WO_B_TIME_TICKS)
|
||||
return wo_builtin_sys(vm, R, ins, msg);
|
||||
if (C >= WO_B_DB_INSERT && C <= WO_B_DB_PROBE) {
|
||||
/* arc stage 3: the database is an actor on shard 0. A worker shard
|
||||
* has no engine by design — its statement marshals, parks, resumes
|
||||
|
|
|
|||
|
|
@ -284,6 +284,14 @@ int wo_builtin_sys(wo_vm *vm, uint64_t *R, uint32_t ins, const char **msg) {
|
|||
vm->cur->park_done = 1;
|
||||
return WO_SYS_PARKED;
|
||||
}
|
||||
case WO_B_TIME_TICKS: { /* the bench clock: CLOCK_MONOTONIC µs as Int.
|
||||
* Never wall time — only differences mean
|
||||
* anything (iteration 22's honest percentiles) */
|
||||
struct timespec mts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &mts);
|
||||
R[A] = (uint64_t)((int64_t)mts.tv_sec * 1000000 + mts.tv_nsec / 1000);
|
||||
return 0;
|
||||
}
|
||||
case WO_B_TIME_LOCAL: { /* Parts: 0 year, 1 month (1..12), 2 day, 3 hour,
|
||||
* 4 minute, 5 second, 6 dow (0 = Sunday) */
|
||||
time_t secs = (time_t)((int64_t)R[B] / 1000);
|
||||
|
|
|
|||
|
|
@ -430,9 +430,13 @@ enum {
|
|||
WO_B_TEXT_OF_BYTES = 83, /* (bytes) -> fresh Text, verbatim. The caller
|
||||
* asserts the bytes are text; no validation,
|
||||
* because Unicode is explicitly out of scope */
|
||||
WO_B_TIME_TICKS = 84, /* () -> Int, CLOCK_MONOTONIC microseconds —
|
||||
* the bench clock (iteration 22). Monotone,
|
||||
* never wall time: immune to NTP steps; only
|
||||
* differences mean anything. */
|
||||
};
|
||||
|
||||
#define WO_B_MAX 83u
|
||||
#define WO_B_MAX 84u
|
||||
/* ids at or above this one live in sysio.c, not builtin.c */
|
||||
#define WO_B_SYS_FIRST WO_B_FS_EXISTS
|
||||
|
||||
|
|
|
|||
2
tests/corpus/run/time-ticks/fixture.out
Normal file
2
tests/corpus/run/time-ticks/fixture.out
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ticks: monotone
|
||||
ticks: nonzero
|
||||
28
tests/corpus/run/time-ticks/fixture.wo
Normal file
28
tests/corpus/run/time-ticks/fixture.wo
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use time
|
||||
|
||||
-- time.ticks: CLOCK_MONOTONIC microseconds as Int. Values are machine
|
||||
-- noise; the fixture asserts existence and ordering — a later reading
|
||||
-- never precedes an earlier one, and a spin's elapsed is non-negative.
|
||||
fn spin(rounds: Int) {
|
||||
let i = 0;
|
||||
while i < rounds {
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Int {
|
||||
let t0 = time.ticks();
|
||||
spin(100000);
|
||||
let t1 = time.ticks();
|
||||
if t1 >= t0 {
|
||||
print("ticks: monotone");
|
||||
} else {
|
||||
print("ticks: BACKWARDS ${t1 - t0}");
|
||||
}
|
||||
if t0 > 0 {
|
||||
print("ticks: nonzero");
|
||||
} else {
|
||||
print("ticks: zero start");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue