Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions src/library_wasi.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,41 +136,37 @@ 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
// this is needed. To get this code to be usable as a JS shim we need to
// 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 }}};
}
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 {
return {{{ cDefs.ENOSYS }}};
}
// "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)) {
Expand All @@ -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;
},

Expand Down
2 changes: 1 addition & 1 deletion src/preamble_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
53 changes: 0 additions & 53 deletions system/lib/libc/emscripten_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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);
15 changes: 15 additions & 0 deletions system/lib/libc/musl/src/time/clock_getres.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
}
8 changes: 8 additions & 0 deletions system/lib/libc/wasi-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <wasi/api.h>
#include <wasi/wasi-helpers.h>

Expand All @@ -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};
}
22 changes: 0 additions & 22 deletions system/lib/standalone/standalone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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?

Expand Down
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_pthreads.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
19495
19491
5 changes: 3 additions & 2 deletions tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down
Loading