From 3d132f9247f61fd7c303b8c8558392e5b32fdb56 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sun, 5 Mar 2023 14:23:24 -0800 Subject: [PATCH] Split up emscripten_time.c. NFC Also use the `weak` macros from musl's internal features.h Split out from #18905 --- system/lib/libc/emscripten_time.c | 80 ++++--------------------------- system/lib/libc/mktime.c | 46 ++++++++++++++++++ system/lib/libc/tzset.c | 24 ++++++++++ tools/system_libs.py | 2 + 4 files changed, 81 insertions(+), 71 deletions(-) create mode 100644 system/lib/libc/mktime.c create mode 100644 system/lib/libc/tzset.c diff --git a/system/lib/libc/emscripten_time.c b/system/lib/libc/emscripten_time.c index ab65df4713817..cee7811e67f0f 100644 --- a/system/lib/libc/emscripten_time.c +++ b/system/lib/libc/emscripten_time.c @@ -15,68 +15,13 @@ // Replaces musl's __tz.c -__attribute__((__weak__)) long timezone = 0; -__attribute__((__weak__)) int daylight = 0; -__attribute__((__weak__)) char *tzname[2] = { 0, 0 }; +weak long timezone = 0; +weak int daylight = 0; +weak char *tzname[2] = { 0, 0 }; -void _tzset_js(long* timezone, int* daylight, char** tzname); -// Declare these functions `int` rather than time_t to avoid int64 at the wasm -// boundary (avoids 64-bit complexity at the boundary when WASM_BIGINT is -// missing). -// TODO(sbc): Covert back to `time_t` before 2038 ... -int _timegm_js(struct tm *tm); -int _mktime_js(struct tm *tm); -void _localtime_js(const time_t *restrict t, struct tm *restrict tm); -void _gmtime_js(const time_t *restrict t, struct tm *restrict tm); double emscripten_get_now_res(); -__attribute__((__weak__)) -void tzset() { - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - static _Atomic bool done_init = false; - if (!done_init) { - pthread_mutex_lock(&lock); - if (!done_init) { - _tzset_js(&timezone, &daylight, tzname); - done_init = true; - } - pthread_mutex_unlock(&lock); - } -} - -__attribute__((__weak__)) -time_t timegm(struct tm *tm) { - tzset(); - return _timegm_js(tm); -} - -__attribute__((__weak__)) -time_t mktime(struct tm *tm) { - tzset(); - return _mktime_js(tm); -} - -__attribute__((__weak__)) -struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm) { - tzset(); - _localtime_js(t, tm); - // __localtime_js sets everything but the tmzone pointer - tm->__tm_zone = tm->tm_isdst ? tzname[1] :tzname[0]; - return tm; -} - -__attribute__((__weak__)) -struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm) { - tzset(); - _gmtime_js(t, tm); - tm->tm_isdst = 0; - tm->__tm_gmtoff = 0; - tm->__tm_zone = "GMT"; - return tm; -} - -__attribute__((__weak__)) -clock_t __clock() { +weak clock_t __clock() { static thread_local double start = 0; if (!start) { start = emscripten_date_now(); @@ -84,8 +29,7 @@ clock_t __clock() { return (emscripten_date_now() - start) * (CLOCKS_PER_SEC / 1000); } -__attribute__((__weak__)) -time_t __time(time_t *t) { +weak time_t __time(time_t *t) { double ret = emscripten_date_now() / 1000; if (t) { *t = ret; @@ -97,8 +41,7 @@ extern bool _emscripten_get_now_is_monotonic(); static thread_local bool checked_monotonic = false; static thread_local bool is_monotonic = 0; -__attribute__((__weak__)) -int __clock_gettime(clockid_t clk, struct timespec *ts) { +weak int __clock_gettime(clockid_t clk, struct timespec *ts) { if (!checked_monotonic) { is_monotonic = _emscripten_get_now_is_monotonic(); checked_monotonic = true; @@ -120,8 +63,7 @@ int __clock_gettime(clockid_t clk, struct timespec *ts) { return 0; } -__attribute__((__weak__)) -int __clock_getres(clockid_t clk, struct timespec *ts) { +weak int __clock_getres(clockid_t clk, struct timespec *ts) { if (!checked_monotonic) { is_monotonic = _emscripten_get_now_is_monotonic(); checked_monotonic = true; @@ -141,8 +83,7 @@ int __clock_getres(clockid_t clk, struct timespec *ts) { return 0; } -__attribute__((__weak__)) -int __gettimeofday(struct timeval *restrict tv, void *restrict tz) { +weak int __gettimeofday(struct timeval *restrict tv, void *restrict tz) { double now_ms = emscripten_date_now(); long long now_s = now_ms / 1000; tv->tv_sec = now_s; // seconds @@ -150,14 +91,11 @@ int __gettimeofday(struct timeval *restrict tv, void *restrict tz) { return 0; } -__attribute__((__weak__)) -int dysize(int year) { +weak int dysize(int year) { int leap = ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))); return leap ? 366 : 365; } -weak_alias(__gmtime_r, gmtime_r); -weak_alias(__localtime_r, localtime_r); weak_alias(__time, time); weak_alias(__clock, clock); weak_alias(__clock_gettime, clock_gettime); diff --git a/system/lib/libc/mktime.c b/system/lib/libc/mktime.c new file mode 100644 index 0000000000000..9f3f9fddc96a9 --- /dev/null +++ b/system/lib/libc/mktime.c @@ -0,0 +1,46 @@ +/* + * Copyright 2023 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ +#include + +// Declare these functions `int` rather than time_t to avoid int64 at the wasm +// boundary (avoids 64-bit complexity at the boundary when WASM_BIGINT is +// missing). +// TODO(sbc): Covert back to `time_t` before 2038 ... +int _timegm_js(struct tm *tm); +int _mktime_js(struct tm *tm); +void _localtime_js(const time_t *restrict t, struct tm *restrict tm); +void _gmtime_js(const time_t *restrict t, struct tm *restrict tm); + +weak time_t timegm(struct tm *tm) { + tzset(); + return _timegm_js(tm); +} + +weak time_t mktime(struct tm *tm) { + tzset(); + return _mktime_js(tm); +} + +weak struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm) { + tzset(); + _localtime_js(t, tm); + // __localtime_js sets everything but the tmzone pointer + tm->__tm_zone = tm->tm_isdst ? tzname[1] :tzname[0]; + return tm; +} + +weak struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm) { + tzset(); + _gmtime_js(t, tm); + tm->tm_isdst = 0; + tm->__tm_gmtoff = 0; + tm->__tm_zone = "GMT"; + return tm; +} + +weak_alias(__gmtime_r, gmtime_r); +weak_alias(__localtime_r, localtime_r); diff --git a/system/lib/libc/tzset.c b/system/lib/libc/tzset.c new file mode 100644 index 0000000000000..a584de4c9d211 --- /dev/null +++ b/system/lib/libc/tzset.c @@ -0,0 +1,24 @@ +/* + * Copyright 2023 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ +#include +#include +#include + +void _tzset_js(long* timezone, int* daylight, char** tzname); + +weak void tzset() { + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + static _Atomic bool done_init = false; + if (!done_init) { + pthread_mutex_lock(&lock); + if (!done_init) { + _tzset_js(&timezone, &daylight, tzname); + done_init = true; + } + pthread_mutex_unlock(&lock); + } +} diff --git a/tools/system_libs.py b/tools/system_libs.py index 41bb2c402e0c8..7b5791aaa6d46 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -1137,6 +1137,8 @@ def get_files(self): 'emscripten_mmap.c', 'emscripten_scan_stack.c', 'emscripten_time.c', + 'mktime.c', + 'tzset.c', 'kill.c', 'pthread_sigmask.c', 'raise.c',