Skip to content

Commit 72e7481

Browse files
Ensure that monotonic clocks really are monotonic (#199)
Resuming wizened snapshots means that clocks don't necessarily stay monotonic. This patch overrides `clock_gettime` to address that, by adding an offset determined at the end of wizening. Signed-off-by: Till Schneidereit <till@tillschneidereit.net>
1 parent 39114a4 commit 72e7481

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

runtime/js.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,33 @@ int main(int argc, const char *argv[]) {
2828
MOZ_ASSERT_UNREACHABLE("main() should not be called");
2929
}
3030

31+
static uint64_t mono_clock_offset = 0;
32+
#define NSECS_PER_SEC 1000000000;
33+
34+
// This overrides wasi-libc's weakly linked implementation of clock_gettime to ensure that
35+
// monotonic clocks really are monotonic, even across resumptions of wizer snapshots.
36+
int clock_gettime(clockid_t clock, timespec * ts) {
37+
__wasi_clockid_t clock_id;
38+
if (clock == CLOCK_REALTIME) {
39+
clock_id = __WASI_CLOCKID_REALTIME;
40+
} else if (clock == CLOCK_MONOTONIC) {
41+
clock_id = __WASI_CLOCKID_MONOTONIC;
42+
} else {
43+
return EINVAL;
44+
}
45+
__wasi_timestamp_t t;
46+
auto errno = __wasi_clock_time_get(clock_id, 1, &t);
47+
if (errno != 0) {
48+
return EINVAL;
49+
}
50+
if (clock == CLOCK_MONOTONIC) {
51+
t += mono_clock_offset;
52+
}
53+
ts->tv_sec = t / NSECS_PER_SEC;
54+
ts->tv_nsec = t % NSECS_PER_SEC;
55+
return 0;
56+
}
57+
3158
void wizen() {
3259
std::string args;
3360
std::getline(std::cin, args);
@@ -37,6 +64,13 @@ void wizen() {
3764
config->pre_initialize = true;
3865
ENGINE = new api::Engine(std::move(config));
3966
ENGINE->finish_pre_initialization();
67+
68+
// Ensure that the monotonic clock is always increasing, even across multiple resumptions.
69+
__wasi_timestamp_t t;
70+
MOZ_RELEASE_ASSERT(!__wasi_clock_time_get(__WASI_CLOCKID_MONOTONIC, 1, &t));
71+
if (mono_clock_offset < t) {
72+
mono_clock_offset = t;
73+
}
4074
}
4175

4276
WIZER_INIT(wizen);

0 commit comments

Comments
 (0)