From 5cc99a395047482bda33499c5eef9b99214a54ee Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Fri, 13 Nov 2026 14:02:46 +0900 Subject: [PATCH] 0.26.3: the processor time on i386; the specification by its minor version The program's processor time and an observation's monotonic clock were read from the sixty-four bit clock_gettime into records of two words; both read okl::ktimespec. tests/word32/runs.cpp measures the processor time of 50 ms of work, which failed before the change. The manifest declares openkal = "^0.25.0": an implementation written against a patch release conforms to every later patch of the minor version (openkal clause 8), so a consumer that names one resolves with it. --- README.md | 15 ++++++++++++++- mcpp.toml | 5 +++-- src/observe.cpp | 4 ++-- src/process.cpp | 2 +- tests/word32/runs.cpp | 13 +++++++++++++ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 980fa9f..846a2e5 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,22 @@ for Linux, written on the kernel's own system-call interface. openkal = "0.25.0" [target.'cfg(os = "linux")'.dependencies] -openkal-linux = "0.26.2" +openkal-linux = "0.26.3" ``` +## What 0.26.3 corrects + +**The processor time on i386.** The program's processor time and the monotonic +clock read for an observation were read from the sixty-four bit `clock_gettime` +into records of two words, so the seconds were taken as the fraction and the +fraction was lost; both read `okl::ktimespec`, the record that call writes. +`tests/word32/runs.cpp` measures the processor time of 50 ms of work. + +**The specification by its minor version.** The manifest declares `openkal = +"^0.25.0"`: an implementation written against a patch release conforms to every +later patch of that minor version (openkal clause 8), and a consumer that names +one resolves with it. + ## What 0.26.2 adds **i386** (openkal 0.25.1, clause 5.5). The kernel's i386 gate (`int $0x80`, the sixth diff --git a/mcpp.toml b/mcpp.toml index 53f0873..784901e 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-linux" -version = "0.26.2" +version = "0.26.3" description = "The reference implementation of openkal for Linux, written on the kernel's own system-call interface so that it can be placed beneath a C library as well as above one." license = "Apache-2.0" @@ -67,7 +67,8 @@ provides-interfaces = [ ] [dependencies] -openkal = "0.25.0" +# Every patch release of the specification's minor version (openkal clause 8). +openkal = "^0.25.0" # The package contributes definitions and no modules. The interface it # implements is declared by the specification package, which this package diff --git a/src/observe.cpp b/src/observe.cpp index 936a0f4..a690bf0 100644 --- a/src/observe.cpp +++ b/src/observe.cpp @@ -464,9 +464,9 @@ struct ring { ring g_ring; okl_u64 monotonic() { - struct { okl_long s, ns; } t{}; + okl::ktimespec t{}; // the time64 record on i386 (sys.h) okl::sys(okl::nr_clock_gettime, 1 /* CLOCK_MONOTONIC */, reinterpret_cast(&t)); - return static_cast(t.s) * 1000000000ull + static_cast(t.ns); + return static_cast(t.sec) * 1000000000ull + static_cast(t.nsec); } void sample(void* uc) { diff --git a/src/process.cpp b/src/process.cpp index bcc9b82..eb8ef95 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -1480,7 +1480,7 @@ okl_u64 ticks_to_ns(okl_u64 t) { bool cpu_ns(okl_long pid, bool self, okl_u64& out) { const okl_long clock = self ? 2 /* CLOCK_PROCESS_CPUTIME_ID */ : static_cast(static_cast((~static_cast(pid)) << 3) | 2); - struct { okl_long sec, nsec; } ts{}; + okl::ktimespec ts{}; // the time64 record on i386 (sys.h) const okl_long r = okl::sys(okl::nr_clock_gettime, clock, reinterpret_cast(&ts)); if (!okl::failed(r)) { out = static_cast(ts.sec) * 1000000000ull + static_cast(ts.nsec); diff --git a/tests/word32/runs.cpp b/tests/word32/runs.cpp index 4564e91..bc67f27 100644 --- a/tests/word32/runs.cpp +++ b/tests/word32/runs.cpp @@ -7,6 +7,7 @@ #include #include #include +#include static int failures = 0; static void say(const char* s) { kal_uintptr n = 0; while (s[n]) ++n; kal_stream_write(kal_stdout(), s, n); } @@ -52,6 +53,18 @@ extern "C" int main(int, char**, char**) { const kal_duration before = kal_time_monotonic(); kal_time_sleep(20u * 1000u * 1000u); check(kal_time_monotonic() - before >= 20u * 1000u * 1000u, "a sleep of 20 ms lasts at least that"); + // The processor time is read through the sixty-four bit clock as well: worked for about + // 50 ms, it is more than 10 ms and less than the time since the program started. + const kal_duration spin = kal_time_monotonic(); + volatile kal_u64 sink = 0; + while (kal_time_monotonic() - spin < 50u * 1000u * 1000u) sink = sink + 1; + kal_process me{}; + kal_program_info pi{}; pi.self_size = sizeof pi; + check(kal_process_self(&me) == kal_ok && kal_process_info(me, KAL_PINFO_CPU, &pi) == kal_ok + && (pi.present & KAL_PINFO_CPU) && pi.cpu_ns > 10u * 1000u * 1000u + && pi.cpu_ns < kal_time_monotonic() - before + 1000u * 1000u * 1000u, + "the processor time counts the work done"); + kal_process_close(me); say(failures ? "FAILED\n" : "all held\n"); return failures; }