diff --git a/src/library_wasi.js b/src/library_wasi.js index 63a202eb52a39..ceca145428409 100644 --- a/src/library_wasi.js +++ b/src/library_wasi.js @@ -136,12 +136,7 @@ var WasiLibrary = { }, #endif - $checkWasiClock: (clock_id) => { - return clock_id == {{{ cDefs.__WASI_CLOCKID_REALTIME }}} || - clock_id == {{{ cDefs.__WASI_CLOCKID_MONOTONIC }}} || - clock_id == {{{ cDefs.__WASI_CLOCKID_PROCESS_CPUTIME_ID }}} || - clock_id == {{{ cDefs.__WASI_CLOCKID_THREAD_CPUTIME_ID }}}; - }, + $checkWasiClock: (clock_id) => clock_id >= {{{ cDefs.__WASI_CLOCKID_REALTIME }}} && clock_id <= {{{ cDefs.__WASI_CLOCKID_THREAD_CPUTIME_ID }}}, // TODO: the i64 in the API here must be legalized for this JS code to run, // but the wasm file can't be legalized in standalone mode, which is where @@ -149,7 +144,8 @@ var WasiLibrary = { // either wait for BigInt support or to legalize on the client. clock_time_get__i53abi: true, clock_time_get__nothrow: true, - clock_time_get__deps: ['emscripten_get_now', '$nowIsMonotonic', '$checkWasiClock'], + clock_time_get__proxy: 'none', + clock_time_get__deps: ['emscripten_get_now', 'emscripten_date_now', '$nowIsMonotonic', '$checkWasiClock'], clock_time_get: (clk_id, ignored_precision, ptime) => { if (!checkWasiClock(clk_id)) { return {{{ cDefs.EINVAL }}}; @@ -157,7 +153,7 @@ var WasiLibrary = { var now; // all wasi clocks but realtime are monotonic if (clk_id === {{{ cDefs.__WASI_CLOCKID_REALTIME }}}) { - now = Date.now(); + now = _emscripten_date_now(); } else if (nowIsMonotonic) { now = _emscripten_get_now(); } else { @@ -165,12 +161,12 @@ var WasiLibrary = { } // "now" is in ms, and wasi times are in ns. var nsec = Math.round(now * 1000 * 1000); - {{{ makeSetValue('ptime', 0, 'nsec >>> 0', 'i32') }}}; - {{{ makeSetValue('ptime', 4, '(nsec / Math.pow(2, 32)) >>> 0', 'i32') }}}; + {{{ makeSetValue('ptime', 0, 'nsec', 'i64') }}}; return 0; }, clock_res_get__nothrow: true, + clock_res_get__proxy: 'none', clock_res_get__deps: ['emscripten_get_now', 'emscripten_get_now_res', '$nowIsMonotonic', '$checkWasiClock'], clock_res_get: (clk_id, pres) => { if (!checkWasiClock(clk_id)) { @@ -185,8 +181,7 @@ var WasiLibrary = { } else { return {{{ cDefs.ENOSYS }}}; } - {{{ makeSetValue('pres', 0, 'nsec >>> 0', 'i32') }}}; - {{{ makeSetValue('pres', 4, '(nsec / Math.pow(2, 32)) >>> 0', 'i32') }}}; + {{{ makeSetValue('pres', 0, 'nsec', 'i64') }}}; return 0; }, diff --git a/src/preamble_minimal.js b/src/preamble_minimal.js index aa216fb510377..a49ca40962d44 100644 --- a/src/preamble_minimal.js +++ b/src/preamble_minimal.js @@ -24,7 +24,7 @@ function abort(what) { throw {{{ ASSERTIONS ? 'new Error(what)' : 'what' }}}; } -#if SAFE_HEAP && !WASM_BIGINT +#if !WASM_BIGINT // Globals used by JS i64 conversions (see makeSetValue) var tempDouble; var tempI64; diff --git a/system/lib/libc/emscripten_time.c b/system/lib/libc/emscripten_time.c index 6c15b250d5796..501b83e0b9434 100644 --- a/system/lib/libc/emscripten_time.c +++ b/system/lib/libc/emscripten_time.c @@ -15,14 +15,6 @@ #include "emscripten_internal.h" -weak clock_t __clock() { - static thread_local double start = 0; - if (!start) { - start = emscripten_date_now(); - } - return (emscripten_date_now() - start) * (CLOCKS_PER_SEC / 1000); -} - weak time_t __time(time_t *t) { double ret = emscripten_date_now() / 1000; if (t) { @@ -34,48 +26,6 @@ weak time_t __time(time_t *t) { static thread_local bool checked_monotonic = false; static thread_local bool is_monotonic = 0; -weak int __clock_gettime(clockid_t clk, struct timespec *ts) { - if (!checked_monotonic) { - is_monotonic = _emscripten_get_now_is_monotonic(); - checked_monotonic = true; - } - - double now_ms; - if (clk == CLOCK_REALTIME) { - now_ms = emscripten_date_now(); - } else if ((clk == CLOCK_MONOTONIC || clk == CLOCK_MONOTONIC_RAW) && is_monotonic) { - now_ms = emscripten_get_now(); - } else { - errno = EINVAL; - return -1; - } - - long long now_s = now_ms / 1000; - ts->tv_sec = now_s; // seconds - ts->tv_nsec = (now_ms - (now_s * 1000)) * 1000 * 1000; // nanoseconds - return 0; -} - -weak int __clock_getres(clockid_t clk, struct timespec *ts) { - if (!checked_monotonic) { - is_monotonic = _emscripten_get_now_is_monotonic(); - checked_monotonic = true; - } - - double nsec; - if (clk == CLOCK_REALTIME) { - nsec = 1000 * 1000; // educated guess that it's milliseconds - } else if (clk == CLOCK_MONOTONIC && is_monotonic) { - nsec = emscripten_get_now_res(); - } else { - errno = EINVAL; - return -1; - } - ts->tv_sec = (nsec / (1000 * 1000 * 1000)); - ts->tv_nsec = nsec; - return 0; -} - weak int __gettimeofday(struct timeval *restrict tv, void *restrict tz) { double now_ms = emscripten_date_now(); long long now_s = now_ms / 1000; @@ -90,7 +40,4 @@ weak int dysize(int year) { } weak_alias(__time, time); -weak_alias(__clock, clock); -weak_alias(__clock_gettime, clock_gettime); -weak_alias(__clock_getres, clock_getres); weak_alias(__gettimeofday, gettimeofday); diff --git a/system/lib/libc/musl/src/time/clock_getres.c b/system/lib/libc/musl/src/time/clock_getres.c index 81c6703761d44..b733fdc00f9d2 100644 --- a/system/lib/libc/musl/src/time/clock_getres.c +++ b/system/lib/libc/musl/src/time/clock_getres.c @@ -3,6 +3,20 @@ int clock_getres(clockid_t clk, struct timespec *ts) { +#ifdef __EMSCRIPTEN__ + // See https://github.com/bytecodealliance/wasmtime/issues/374 + if (clk > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk < 0) { + errno = EINVAL; + return -1; + } + __wasi_timestamp_t res; + __wasi_errno_t error = __wasi_clock_res_get(clk, &res); + if (error != __WASI_ERRNO_SUCCESS) { + return __wasi_syscall_ret(error); + } + *ts = __wasi_timestamp_to_timespec(res); + return 0; +#else #ifdef SYS_clock_getres_time64 /* On a 32-bit arch, use the old syscall if it exists. */ if (SYS_clock_getres != SYS_clock_getres_time64) { @@ -18,4 +32,5 @@ int clock_getres(clockid_t clk, struct timespec *ts) /* If reaching this point, it's a 64-bit arch or time64-only * 32-bit arch and we can get result directly into timespec. */ return syscall(SYS_clock_getres, clk, ts); +#endif } diff --git a/system/lib/libc/wasi-helpers.c b/system/lib/libc/wasi-helpers.c index b71ac92c804ce..0eaba304e980e 100644 --- a/system/lib/libc/wasi-helpers.c +++ b/system/lib/libc/wasi-helpers.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -26,3 +27,10 @@ int __wasi_fd_is_valid(__wasi_fd_t fd) { } return 1; } + +#define NSEC_PER_SEC (1000 * 1000 * 1000) + +struct timespec __wasi_timestamp_to_timespec(__wasi_timestamp_t timestamp) { + return (struct timespec){.tv_sec = timestamp / NSEC_PER_SEC, + .tv_nsec = timestamp % NSEC_PER_SEC}; +} diff --git a/system/lib/standalone/standalone.c b/system/lib/standalone/standalone.c index 52c3eb3360b36..3a910ba662d62 100644 --- a/system/lib/standalone/standalone.c +++ b/system/lib/standalone/standalone.c @@ -45,28 +45,6 @@ _Static_assert(CLOCK_MONOTONIC == __WASI_CLOCKID_MONOTONIC, "must match"); _Static_assert(CLOCK_PROCESS_CPUTIME_ID == __WASI_CLOCKID_PROCESS_CPUTIME_ID, "must match"); _Static_assert(CLOCK_THREAD_CPUTIME_ID == __WASI_CLOCKID_THREAD_CPUTIME_ID, "must match"); -#define NSEC_PER_SEC (1000 * 1000 * 1000) - -struct timespec __wasi_timestamp_to_timespec(__wasi_timestamp_t timestamp) { - return (struct timespec){.tv_sec = timestamp / NSEC_PER_SEC, - .tv_nsec = timestamp % NSEC_PER_SEC}; -} - -int clock_getres(clockid_t clk_id, struct timespec *tp) { - // See https://github.com/bytecodealliance/wasmtime/issues/3714 - if (clk_id > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk_id < 0) { - errno = EINVAL; - return -1; - } - __wasi_timestamp_t res; - __wasi_errno_t error = __wasi_clock_res_get(clk_id, &res); - if (error != __WASI_ERRNO_SUCCESS) { - return __wasi_syscall_ret(error); - } - *tp = __wasi_timestamp_to_timespec(res); - return 0; -} - // mmap support is nonexistent. TODO: emulate simple mmaps using // stdio + malloc, which is slow but may help some things? diff --git a/test/other/codesize/test_codesize_minimal_pthreads.size b/test/other/codesize/test_codesize_minimal_pthreads.size index a02c1cabcd235..6dc04c8da057f 100644 --- a/test/other/codesize/test_codesize_minimal_pthreads.size +++ b/test/other/codesize/test_codesize_minimal_pthreads.size @@ -1 +1 @@ -19495 +19491 diff --git a/tools/system_libs.py b/tools/system_libs.py index 6f25349163344..29d1a68f6ae36 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -1223,7 +1223,10 @@ def get_files(self): 'gmtime.c', 'localtime.c', 'nanosleep.c', + 'clock.c', 'clock_nanosleep.c', + 'clock_getres.c', + 'clock_gettime.c', 'ctime_r.c', 'timespec_get.c', 'utime.c', @@ -2216,8 +2219,6 @@ def get_files(self): path='system/lib/libc/musl/src/time', filenames=['__secs_to_tm.c', '__tz.c', - 'clock.c', - 'clock_gettime.c', 'gettimeofday.c', 'localtime_r.c', 'gmtime_r.c',