| 1 | #define _WASI_EMULATED_PROCESS_CLOCKS |
| 2 | #include <time.h> |
| 3 | #include <wasi/api.h> |
| 4 | #include <common/time.h> |
| 5 | |
| 6 | _Static_assert( |
| 7 | CLOCKS_PER_SEC == NSEC_PER_SEC, |
| 8 | "This implementation assumes that `clock` is in nanoseconds" |
| 9 | ); |
| 10 | |
| 11 | // Snapshot of the monotonic clock at the start of the program. |
| 12 | static __wasi_timestamp_t start; |
| 13 | |
| 14 | // Use a priority of 10 to run fairly early in the implementation-reserved |
| 15 | // constructor priority range. |
| 16 | __attribute__((constructor(10))) |
| 17 | static void init(void) { |
| 18 | (void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &start); |
| 19 | } |
| 20 | |
| 21 | // Define the libc symbol as `__clock` so that we can reliably call it |
| 22 | // from elsewhere in libc. |
| 23 | clock_t __clock(void) { |
| 24 | // Use `MONOTONIC` instead of `PROCESS_CPUTIME_ID` since WASI doesn't have |
| 25 | // an inherent concept of a process. Note that this means we'll incorrectly |
| 26 | // include time from other processes, so this function is only declared by |
| 27 | // the headers if `_WASI_EMULATED_PROCESS_CLOCKS` is defined. |
| 28 | __wasi_timestamp_t now = 0; |
| 29 | (void)__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 0, &now); |
| 30 | return now - start; |
| 31 | } |
| 32 | |
| 33 | // Define a user-visible alias as a weak symbol. |
| 34 | __attribute__((__weak__, __alias__("__clock"))) |
| 35 | clock_t clock(void); |