1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use std::mem;

use libc::{
    clock_getres, clock_gettime, timespec, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID,
    CLOCK_REALTIME, CLOCK_THREAD_CPUTIME_ID,
};
use wasmer::WasmRef;
use wasmer_wasix_types::wasi::{Errno, Snapshot0Clockid, Timestamp};

use crate::syscalls::types::*;

pub fn platform_clock_res_get(
    clock_id: Snapshot0Clockid,
    resolution: WasmRef<Timestamp>,
) -> Result<i64, Errno> {
    let unix_clock_id = match clock_id {
        Snapshot0Clockid::Monotonic => CLOCK_MONOTONIC,
        Snapshot0Clockid::ProcessCputimeId => CLOCK_PROCESS_CPUTIME_ID,
        Snapshot0Clockid::Realtime => CLOCK_REALTIME,
        Snapshot0Clockid::ThreadCputimeId => CLOCK_THREAD_CPUTIME_ID,
        _ => return Err(Errno::Inval),
    };

    let (output, timespec_out) = unsafe {
        let mut timespec_out: timespec = timespec {
            tv_sec: 0,
            tv_nsec: 0,
        };
        (clock_getres(unix_clock_id, &mut timespec_out), timespec_out)
    };

    let t_out = (timespec_out.tv_sec * 1_000_000_000).wrapping_add(timespec_out.tv_nsec);
    Ok(t_out)
}

pub fn platform_clock_time_get(
    clock_id: Snapshot0Clockid,
    precision: Timestamp,
) -> Result<i64, Errno> {
    let unix_clock_id = match clock_id {
        Snapshot0Clockid::Monotonic => CLOCK_MONOTONIC,
        Snapshot0Clockid::ProcessCputimeId => CLOCK_PROCESS_CPUTIME_ID,
        Snapshot0Clockid::Realtime => CLOCK_REALTIME,
        Snapshot0Clockid::ThreadCputimeId => CLOCK_THREAD_CPUTIME_ID,
        _ => return Err(Errno::Inval),
    };

    let (output, timespec_out) = unsafe {
        let mut timespec_out: timespec = timespec {
            tv_sec: 0,
            tv_nsec: 0,
        };
        (
            clock_gettime(unix_clock_id, &mut timespec_out),
            timespec_out,
        )
    };

    let t_out = (timespec_out.tv_sec * 1_000_000_000).wrapping_add(timespec_out.tv_nsec);
    Ok(t_out)
}