Skip to content

Commit c35d60a

Browse files
authored
Unify two separate clock_getres and clock_gettime implementations. NFC (#23063)
1 parent 88820b6 commit c35d60a

File tree

8 files changed

+35
-91
lines changed

8 files changed

+35
-91
lines changed

src/library_wasi.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,41 +136,37 @@ var WasiLibrary = {
136136
},
137137
#endif
138138

139-
$checkWasiClock: (clock_id) => {
140-
return clock_id == {{{ cDefs.__WASI_CLOCKID_REALTIME }}} ||
141-
clock_id == {{{ cDefs.__WASI_CLOCKID_MONOTONIC }}} ||
142-
clock_id == {{{ cDefs.__WASI_CLOCKID_PROCESS_CPUTIME_ID }}} ||
143-
clock_id == {{{ cDefs.__WASI_CLOCKID_THREAD_CPUTIME_ID }}};
144-
},
139+
$checkWasiClock: (clock_id) => clock_id >= {{{ cDefs.__WASI_CLOCKID_REALTIME }}} && clock_id <= {{{ cDefs.__WASI_CLOCKID_THREAD_CPUTIME_ID }}},
145140

146141
// TODO: the i64 in the API here must be legalized for this JS code to run,
147142
// but the wasm file can't be legalized in standalone mode, which is where
148143
// this is needed. To get this code to be usable as a JS shim we need to
149144
// either wait for BigInt support or to legalize on the client.
150145
clock_time_get__i53abi: true,
151146
clock_time_get__nothrow: true,
152-
clock_time_get__deps: ['emscripten_get_now', '$nowIsMonotonic', '$checkWasiClock'],
147+
clock_time_get__proxy: 'none',
148+
clock_time_get__deps: ['emscripten_get_now', 'emscripten_date_now', '$nowIsMonotonic', '$checkWasiClock'],
153149
clock_time_get: (clk_id, ignored_precision, ptime) => {
154150
if (!checkWasiClock(clk_id)) {
155151
return {{{ cDefs.EINVAL }}};
156152
}
157153
var now;
158154
// all wasi clocks but realtime are monotonic
159155
if (clk_id === {{{ cDefs.__WASI_CLOCKID_REALTIME }}}) {
160-
now = Date.now();
156+
now = _emscripten_date_now();
161157
} else if (nowIsMonotonic) {
162158
now = _emscripten_get_now();
163159
} else {
164160
return {{{ cDefs.ENOSYS }}};
165161
}
166162
// "now" is in ms, and wasi times are in ns.
167163
var nsec = Math.round(now * 1000 * 1000);
168-
{{{ makeSetValue('ptime', 0, 'nsec >>> 0', 'i32') }}};
169-
{{{ makeSetValue('ptime', 4, '(nsec / Math.pow(2, 32)) >>> 0', 'i32') }}};
164+
{{{ makeSetValue('ptime', 0, 'nsec', 'i64') }}};
170165
return 0;
171166
},
172167

173168
clock_res_get__nothrow: true,
169+
clock_res_get__proxy: 'none',
174170
clock_res_get__deps: ['emscripten_get_now', 'emscripten_get_now_res', '$nowIsMonotonic', '$checkWasiClock'],
175171
clock_res_get: (clk_id, pres) => {
176172
if (!checkWasiClock(clk_id)) {
@@ -185,8 +181,7 @@ var WasiLibrary = {
185181
} else {
186182
return {{{ cDefs.ENOSYS }}};
187183
}
188-
{{{ makeSetValue('pres', 0, 'nsec >>> 0', 'i32') }}};
189-
{{{ makeSetValue('pres', 4, '(nsec / Math.pow(2, 32)) >>> 0', 'i32') }}};
184+
{{{ makeSetValue('pres', 0, 'nsec', 'i64') }}};
190185
return 0;
191186
},
192187

src/preamble_minimal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function abort(what) {
2424
throw {{{ ASSERTIONS ? 'new Error(what)' : 'what' }}};
2525
}
2626

27-
#if SAFE_HEAP && !WASM_BIGINT
27+
#if !WASM_BIGINT
2828
// Globals used by JS i64 conversions (see makeSetValue)
2929
var tempDouble;
3030
var tempI64;

system/lib/libc/emscripten_time.c

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515

1616
#include "emscripten_internal.h"
1717

18-
weak clock_t __clock() {
19-
static thread_local double start = 0;
20-
if (!start) {
21-
start = emscripten_date_now();
22-
}
23-
return (emscripten_date_now() - start) * (CLOCKS_PER_SEC / 1000);
24-
}
25-
2618
weak time_t __time(time_t *t) {
2719
double ret = emscripten_date_now() / 1000;
2820
if (t) {
@@ -34,48 +26,6 @@ weak time_t __time(time_t *t) {
3426
static thread_local bool checked_monotonic = false;
3527
static thread_local bool is_monotonic = 0;
3628

37-
weak int __clock_gettime(clockid_t clk, struct timespec *ts) {
38-
if (!checked_monotonic) {
39-
is_monotonic = _emscripten_get_now_is_monotonic();
40-
checked_monotonic = true;
41-
}
42-
43-
double now_ms;
44-
if (clk == CLOCK_REALTIME) {
45-
now_ms = emscripten_date_now();
46-
} else if ((clk == CLOCK_MONOTONIC || clk == CLOCK_MONOTONIC_RAW) && is_monotonic) {
47-
now_ms = emscripten_get_now();
48-
} else {
49-
errno = EINVAL;
50-
return -1;
51-
}
52-
53-
long long now_s = now_ms / 1000;
54-
ts->tv_sec = now_s; // seconds
55-
ts->tv_nsec = (now_ms - (now_s * 1000)) * 1000 * 1000; // nanoseconds
56-
return 0;
57-
}
58-
59-
weak int __clock_getres(clockid_t clk, struct timespec *ts) {
60-
if (!checked_monotonic) {
61-
is_monotonic = _emscripten_get_now_is_monotonic();
62-
checked_monotonic = true;
63-
}
64-
65-
double nsec;
66-
if (clk == CLOCK_REALTIME) {
67-
nsec = 1000 * 1000; // educated guess that it's milliseconds
68-
} else if (clk == CLOCK_MONOTONIC && is_monotonic) {
69-
nsec = emscripten_get_now_res();
70-
} else {
71-
errno = EINVAL;
72-
return -1;
73-
}
74-
ts->tv_sec = (nsec / (1000 * 1000 * 1000));
75-
ts->tv_nsec = nsec;
76-
return 0;
77-
}
78-
7929
weak int __gettimeofday(struct timeval *restrict tv, void *restrict tz) {
8030
double now_ms = emscripten_date_now();
8131
long long now_s = now_ms / 1000;
@@ -90,7 +40,4 @@ weak int dysize(int year) {
9040
}
9141

9242
weak_alias(__time, time);
93-
weak_alias(__clock, clock);
94-
weak_alias(__clock_gettime, clock_gettime);
95-
weak_alias(__clock_getres, clock_getres);
9643
weak_alias(__gettimeofday, gettimeofday);

system/lib/libc/musl/src/time/clock_getres.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33

44
int clock_getres(clockid_t clk, struct timespec *ts)
55
{
6+
#ifdef __EMSCRIPTEN__
7+
// See https://github.com/bytecodealliance/wasmtime/issues/374
8+
if (clk > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk < 0) {
9+
errno = EINVAL;
10+
return -1;
11+
}
12+
__wasi_timestamp_t res;
13+
__wasi_errno_t error = __wasi_clock_res_get(clk, &res);
14+
if (error != __WASI_ERRNO_SUCCESS) {
15+
return __wasi_syscall_ret(error);
16+
}
17+
*ts = __wasi_timestamp_to_timespec(res);
18+
return 0;
19+
#else
620
#ifdef SYS_clock_getres_time64
721
/* On a 32-bit arch, use the old syscall if it exists. */
822
if (SYS_clock_getres != SYS_clock_getres_time64) {
@@ -18,4 +32,5 @@ int clock_getres(clockid_t clk, struct timespec *ts)
1832
/* If reaching this point, it's a 64-bit arch or time64-only
1933
* 32-bit arch and we can get result directly into timespec. */
2034
return syscall(SYS_clock_getres, clk, ts);
35+
#endif
2136
}

system/lib/libc/wasi-helpers.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <errno.h>
99
#include <stdlib.h>
10+
#include <time.h>
1011
#include <wasi/api.h>
1112
#include <wasi/wasi-helpers.h>
1213

@@ -26,3 +27,10 @@ int __wasi_fd_is_valid(__wasi_fd_t fd) {
2627
}
2728
return 1;
2829
}
30+
31+
#define NSEC_PER_SEC (1000 * 1000 * 1000)
32+
33+
struct timespec __wasi_timestamp_to_timespec(__wasi_timestamp_t timestamp) {
34+
return (struct timespec){.tv_sec = timestamp / NSEC_PER_SEC,
35+
.tv_nsec = timestamp % NSEC_PER_SEC};
36+
}

system/lib/standalone/standalone.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,6 @@ _Static_assert(CLOCK_MONOTONIC == __WASI_CLOCKID_MONOTONIC, "must match");
4545
_Static_assert(CLOCK_PROCESS_CPUTIME_ID == __WASI_CLOCKID_PROCESS_CPUTIME_ID, "must match");
4646
_Static_assert(CLOCK_THREAD_CPUTIME_ID == __WASI_CLOCKID_THREAD_CPUTIME_ID, "must match");
4747

48-
#define NSEC_PER_SEC (1000 * 1000 * 1000)
49-
50-
struct timespec __wasi_timestamp_to_timespec(__wasi_timestamp_t timestamp) {
51-
return (struct timespec){.tv_sec = timestamp / NSEC_PER_SEC,
52-
.tv_nsec = timestamp % NSEC_PER_SEC};
53-
}
54-
55-
int clock_getres(clockid_t clk_id, struct timespec *tp) {
56-
// See https://github.com/bytecodealliance/wasmtime/issues/3714
57-
if (clk_id > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk_id < 0) {
58-
errno = EINVAL;
59-
return -1;
60-
}
61-
__wasi_timestamp_t res;
62-
__wasi_errno_t error = __wasi_clock_res_get(clk_id, &res);
63-
if (error != __WASI_ERRNO_SUCCESS) {
64-
return __wasi_syscall_ret(error);
65-
}
66-
*tp = __wasi_timestamp_to_timespec(res);
67-
return 0;
68-
}
69-
7048
// mmap support is nonexistent. TODO: emulate simple mmaps using
7149
// stdio + malloc, which is slow but may help some things?
7250

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19495
1+
19491

tools/system_libs.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,10 @@ def get_files(self):
12231223
'gmtime.c',
12241224
'localtime.c',
12251225
'nanosleep.c',
1226+
'clock.c',
12261227
'clock_nanosleep.c',
1228+
'clock_getres.c',
1229+
'clock_gettime.c',
12271230
'ctime_r.c',
12281231
'timespec_get.c',
12291232
'utime.c',
@@ -2216,8 +2219,6 @@ def get_files(self):
22162219
path='system/lib/libc/musl/src/time',
22172220
filenames=['__secs_to_tm.c',
22182221
'__tz.c',
2219-
'clock.c',
2220-
'clock_gettime.c',
22212222
'gettimeofday.c',
22222223
'localtime_r.c',
22232224
'gmtime_r.c',

0 commit comments

Comments
 (0)