Stream: wasi

Topic: sharing clock with host


view this post on Zulip Mats Brorsson (Jul 20 2023 at 10:32):

I am trying to do some measurements where I would like to take a timestamp in the runtime and then relate that to a timestamp in the webassembly code. However, it seems as the CLOCK_REALTIME with clock_gettime does not return the struct timespec in relation to Epoch as I get much lower value in the WebAssembly code than on the host.

What would be the best way to get a sane absolute timing measurement from WebAssembly? Should I write host functions for that?

view this post on Zulip Pat Hickey (Jul 20 2023 at 16:46):

wasmtime's clock_realtime is implemented by the system clock by default - the timestamp should indeed be relative to the unix epoch

view this post on Zulip Pat Hickey (Jul 20 2023 at 16:54):

[phickey@pch-tower:crates/test-programs]% git diff wasi-tests/
diff --git a/crates/test-programs/wasi-tests/src/bin/clock_time_get.rs b/crates/test-programs/wasi-tests/src/bin/clock_time_get.rs
index fcfcd582d..de2f7bf0b 100644
--- a/crates/test-programs/wasi-tests/src/bin/clock_time_get.rs
+++ b/crates/test-programs/wasi-tests/src/bin/clock_time_get.rs
@@ -4,11 +4,19 @@ unsafe fn test_clock_time_get() {
     // clock_res_get is where information about precision can be provided.
     wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 1).expect("precision 1 should work");

-    let first_time =
-        wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 0).expect("precision 0 should work");
+    let m1 = wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 0).expect("precision 0 should work");
+    println!("monotonic 1: {m1:?}");

-    let time = wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 0).expect("re-fetch time should work");
-    assert!(first_time <= time, "CLOCK_MONOTONIC should be monotonic");
+    let m2 = wasi::clock_time_get(wasi::CLOCKID_MONOTONIC, 0).expect("re-fetch time should work");
+    assert!(m1 <= m2, "CLOCK_MONOTONIC should be monotonic");
+    println!("monotonic 2: {m2:?}");
+
+    let r1 =
+        wasi::clock_time_get(wasi::CLOCKID_REALTIME, 1).expect("realtime precision 1 should work");
+    println!("realtime 1: {r1:?}");
+    let r2 =
+        wasi::clock_time_get(wasi::CLOCKID_REALTIME, 0).expect("realtime precision 0 should work");
+    println!("realtime 2: {r2:?}");
 }

 fn main() {
[phickey@pch-tower:crates/test-programs]% cargo test --features test_programs --test wasi-cap-std-sync -- clock_time_get --nocapture
    Finished test [unoptimized + debuginfo] target(s) in 0.17s
     Running tests/wasi-cap-std-sync.rs (/home/phickey/src/wasmtime/target/debug/deps/wasi_cap_std_sync-340d657262687994)

running 1 test
preopen: TempDir { path: "/tmp/wasi_cap_std_sync_clock_time_get_ExKBMv" }
monotonic 1: 1226758002
monotonic 2: 1226815901
realtime 1: 1689872051387151567
realtime 2: 1689872051387163937
test clock_time_get ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 45 filtered out; finished in 1.23s

view this post on Zulip Pat Hickey (Jul 20 2023 at 16:55):

1689872051387151567 is GMT: Thursday, July 20, 2023 4:54:11.387 PM

view this post on Zulip Mats Brorsson (Jul 20 2023 at 17:20):

Thanks, There is, however, something strange happening. Here is a sample output:

 ~/wasm/wabench/calibrate [Timestamps ↓·7| 32 1]
19:14 $ ./calibrate
Read time: 1689873255, 858222508
Read millis: 1689873255000, 858
 ~/wasm/wabench/calibrate [Timestamps ↓·7| 32 1]
19:14 $ wasmtime calibrate.wasm
Read time: 1689873258, 0
Read millis: 1951110672, 732

The row beginning with "Read time" prints the values of ts.tv_sec and ts.tv_nsec. They look reasonable in both cases except that the nsec value is 0 when running in wasmtime.
In the row beginning with "Read millis" I am multiplying seconds with 1000 and dividing nanoseconds with 1000000 to get milliseconds. The idea is to add them to get a millisecond value of time. However, the multiplication of seconds doesn't seem to be made for the seconds value and weirdly enough although the nano seconds value is 0, I get some value when dividing with 1000000. I am assuming this has something to do with limited bit-field values in WebAssembly.

view this post on Zulip Pat Hickey (Jul 20 2023 at 17:31):

i dont know what a limited bit field value in webassembly would be. wasi is passing the timestamp as a u64 of nanoseconds to the guest, and as shown in my print those nanoseconds have non-zero digits all the way down

view this post on Zulip Mats Brorsson (Jul 21 2023 at 07:43):

I found the issue. In C for WASI time_t has to be long long while it was sufficient for it to be long on an x64 platform.

view this post on Zulip Ralph (Jul 21 2023 at 09:08):

glad you found that; doc it somewhere!

view this post on Zulip Andrew Brown (Jul 21 2023 at 20:52):

@Mats Brorsson, I ran across something similar recently: does wasi-libc need this updated type?


Last updated: Oct 23 2024 at 20:03 UTC