Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
8213-erts-configure-option-for-ensuring-monoton...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 8213-erts-configure-option-for-ensuring-monotonicity-of-O.patch of Package erlang
From 9ba3b326e5f3a25faa977f73314d1481fbdd7805 Mon Sep 17 00:00:00 2001 From: Rickard Green <rickard@erlang.org> Date: Tue, 26 Mar 2024 17:52:12 +0100 Subject: [PATCH 3/3] [erts] configure option for ensuring monotonicity of OS monotonic time --- HOWTO/INSTALL.md | 8 +++ erts/config.h.in | 4 ++ erts/configure | 26 +++++++++ erts/configure.in | 9 +++ erts/emulator/beam/erl_lock_check.c | 6 +- erts/emulator/beam/erl_time_sup.c | 87 ++++++++++++++++++++++++----- erts/emulator/beam/sys.h | 4 ++ make/configure | 18 ++++++ make/configure.in | 4 ++ 9 files changed, 150 insertions(+), 16 deletions(-) diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md index e7fb4ad27a..3c634f769a 100644 --- a/HOWTO/INSTALL.md +++ b/HOWTO/INSTALL.md @@ -420,6 +420,14 @@ Some of the available `configure` options are: time, and OS monotonic time with higher or lower resolution than chosen by default. Note that both alternatives may have a negative impact on the performance and scalability compared to the default clock sources chosen. +* `--enable-ensure-os-monotonic-time` - Enable functionality ensuring the + monotonicity of monotonic timestamps delivered by the OS. When a + non-monotonic timestamp is detected, it will be replaced by the last + delivered monotonic timestamp before being used by Erlang's time + functionality. Note that you do *not* want to enable this unless the OS + monotonic time source on the system fails to produce monotonic timestamps. + This since ensuring the monotonicity of OS monotonic timestamps will hurt + scalability and performance of the system. * `--disable-saved-compile-time` - Disable saving of compile date and time in the emulator binary. * `--enable-ei-dynamic-lib` - Make erl\_interface build a shared library in addition diff --git a/erts/config.h.in b/erts/config.h.in index 8295b90410..4e0cd90e60 100644 --- a/erts/config.h.in +++ b/erts/config.h.in @@ -51,6 +51,10 @@ /* Define > 0 if big-endian < 0 if little-endian, or 0 if unknown */ #undef ERTS_ENDIANNESS +/* Define if ensurance of the monotonicity of OS monotonic timestamps should + be enabled */ +#undef ERTS_ENSURE_OS_MONOTONIC_TIME + /* Define if OS monotonic clock is corrected */ #undef ERTS_HAVE_CORRECTED_OS_MONOTONIC_TIME diff --git a/erts/configure b/erts/configure index 7da8d32a1b..312ed0b5a1 100755 --- a/erts/configure +++ b/erts/configure @@ -812,6 +812,7 @@ enable_vm_probes with_assumed_cache_line_size enable_systemd with_microstate_accounting +enable_ensure_os_monotonic_time enable_static_nifs enable_static_drivers with_ets_write_concurrency_locks @@ -1525,6 +1526,17 @@ Optional Features: possible if --with-dynamic-trace is enabled, and then default) --enable-systemd enable systemd support in epmd + --enable-ensure-os-monotonic-time + enable functionality ensuring the monotonicity of + monotonic timestamps delivered by the OS. When a + non-monotonic timestamp is detected, it will be + replaced by the last delivered monotonic timestamp + before being used by Erlang's time functionality. + Note that you do *not* want to enable this unless + the OS monotonic time source on the system fails to + produce monotonic timestamps. This since ensuring + the monotonicity of OS monotonic timestamps will + hurt scalability and performance of the system. --disable-saved-compile-time disable saved compile time --enable-static-nifs link nifs statically. If yes then all nifs in all @@ -4193,6 +4205,20 @@ $as_echo "#define ERTS_ENABLE_MSACC 2" >>confdefs.h *) ;; esac +# Check whether --enable-ensure-os-monotonic-time was given. +if test "${enable_ensure_os_monotonic_time+set}" = set; then : + enableval=$enable_ensure_os_monotonic_time; +fi + + +if test "$enable_ensure_os_monotonic_time" = "yes"; then : + + +$as_echo "#define ERTS_ENSURE_OS_MONOTONIC_TIME 1" >>confdefs.h + + +fi + OTP_RELEASE= if test "${ERLANG_COMMERCIAL_BUILD}" != ""; then OTP_EXTRA_FLAGS=-DOTP_RELEASE diff --git a/erts/configure.in b/erts/configure.in index beff4275f8..fecf9c901f 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -309,6 +309,15 @@ case "$with_microstate_accounting" in *) ;; esac +AC_ARG_ENABLE(ensure-os-monotonic-time, +AS_HELP_STRING([--enable-ensure-os-monotonic-time], + [enable functionality ensuring the monotonicity of monotonic timestamps delivered by the OS. When a non-monotonic timestamp is detected, it will be replaced by the last delivered monotonic timestamp before being used by Erlang's time functionality. Note that you do *not* want to enable this unless the OS monotonic time source on the system fails to produce monotonic timestamps. This since ensuring the monotonicity of OS monotonic timestamps will hurt scalability and performance of the system.])) + +AS_IF([test "$enable_ensure_os_monotonic_time" = "yes"], [ + AC_DEFINE(ERTS_ENSURE_OS_MONOTONIC_TIME, [1], + [Define if ensurance of the monotonicity of OS monotonic timestamps should be enabled]) + ]) + dnl Magic test for clearcase. OTP_RELEASE= if test "${ERLANG_COMMERCIAL_BUILD}" != ""; then diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index db1e6e0e66..c16748d7c5 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -163,7 +163,10 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "os_monotonic_time", NULL }, { "erts_alloc_hard_debug", NULL }, { "hard_dbg_mseg", NULL }, - { "erts_mmap", NULL } + { "erts_mmap", NULL }, +#ifdef ERTS_ENSURE_OS_MONOTONIC_TIME + { "ensure_os_monotonic_time", NULL } +#endif }; #define ERTS_LOCK_ORDER_SIZE \ diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c index 5c5ab22172..2faf663157 100644 --- a/erts/emulator/beam/erl_time_sup.c +++ b/erts/emulator/beam/erl_time_sup.c @@ -36,7 +36,7 @@ #include "erl_driver.h" #include "erl_nif.h" #include "erl_proc_sig_queue.h" - + static erts_mtx_t erts_get_time_mtx; /* used by erts_runtime_elapsed_both */ @@ -173,6 +173,10 @@ struct time_sup_infrequently_changed__ { struct time_sup_frequently_changed__ { ErtsMonotonicTime last_not_corrected_time; +#ifdef ERTS_ENSURE_OS_MONOTONIC_TIME + erts_mtx_t mtime_mtx; + ErtsMonotonicTime last_delivered_mtime; +#endif }; static struct { @@ -210,6 +214,49 @@ get_time_offset(void) return (ErtsMonotonicTime) erts_atomic64_read_acqb(&time_sup.inf.c.offset); } +#if !defined(ERTS_ENSURE_OS_MONOTONIC_TIME) + +static ERTS_INLINE ErtsMonotonicTime +os_monotonic_time(void) +{ + return erts_os_monotonic_time(); +} + +static ERTS_INLINE void +os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep) +{ + erts_os_times(mtimep, stimep); +} + +#else /* defined(ERTS_ENSURE_OS_MONOTONIC_TIME) */ + +static ERTS_INLINE ErtsMonotonicTime +verify_os_monotonic_time(ErtsMonotonicTime mtime) +{ + erts_mtx_lock(&time_sup.f.c.mtime_mtx); + if (mtime < time_sup.f.c.last_delivered_mtime) + mtime = time_sup.f.c.last_delivered_mtime; + else + time_sup.f.c.last_delivered_mtime = mtime; + erts_mtx_unlock(&time_sup.f.c.mtime_mtx); + return mtime; +} + +static ERTS_INLINE ErtsMonotonicTime +os_monotonic_time(void) +{ + return verify_os_monotonic_time(erts_os_monotonic_time()); +} + +static ERTS_INLINE void +os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep) +{ + erts_os_times(mtimep, stimep); + *mtimep = verify_os_monotonic_time(*mtimep); +} + +#endif + static ERTS_INLINE void update_last_mtime(ErtsSchedulerData *esdp, ErtsMonotonicTime mtime) { @@ -250,7 +297,6 @@ check_os_monotonic_time(ErtsSchedulerData *esdp, ErtsMonotonicTime mtime) #endif } - #ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT /* @@ -319,7 +365,7 @@ read_corrected_time(int os_drift_corrected, ErtsSchedulerData *esdp) erts_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx); - os_mtime = erts_os_monotonic_time(); + os_mtime = os_monotonic_time(); if (os_mtime >= time_sup.inf.c.parmon.cdata.insts.curr.os_mtime) ci = time_sup.inf.c.parmon.cdata.insts.curr; @@ -415,7 +461,7 @@ check_time_correction(void *vesdp) erts_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx); - erts_os_times(&os_mtime, &os_stime); + os_times(&os_mtime, &os_stime); ci = time_sup.inf.c.parmon.cdata.insts.curr; @@ -684,9 +730,11 @@ check_time_correction(void *vesdp) #endif if (set_new_correction) { + ErtsMonotonicTime cstart_os_mtime; + erts_rwmtx_rwlock(&time_sup.inf.c.parmon.rwmtx); - os_mtime = erts_os_monotonic_time(); + os_mtime = os_monotonic_time(); /* Save previous correction instance */ time_sup.inf.c.parmon.cdata.insts.prev = ci; @@ -695,21 +743,21 @@ check_time_correction(void *vesdp) * Current correction instance begin when * OS monotonic time has increased two units. */ - os_mtime += 2; + cstart_os_mtime = os_mtime + 2; /* * Erlang monotonic time corresponding to * next OS monotonic time using previous * correction. */ - erl_mtime = calc_corrected_erl_mtime(os_mtime, &ci, NULL, + erl_mtime = calc_corrected_erl_mtime(cstart_os_mtime, &ci, NULL, os_drift_corrected); /* * Save new current correction instance. */ time_sup.inf.c.parmon.cdata.insts.curr.erl_mtime = erl_mtime; - time_sup.inf.c.parmon.cdata.insts.curr.os_mtime = os_mtime; + time_sup.inf.c.parmon.cdata.insts.curr.os_mtime = cstart_os_mtime; time_sup.inf.c.parmon.cdata.insts.curr.correction = new_correction; erts_rwmtx_rwunlock(&time_sup.inf.c.parmon.rwmtx); @@ -728,7 +776,7 @@ static ErtsMonotonicTime get_os_corrected_time(ErtsSchedulerData *esdp) { ErtsMonotonicTime os_mtime; ASSERT(time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE); - os_mtime = erts_os_monotonic_time(); + os_mtime = os_monotonic_time(); check_os_monotonic_time(esdp, os_mtime); return os_mtime + time_sup.r.o.moffset; } @@ -742,7 +790,7 @@ check_time_offset(void *vesdp) ASSERT(time_sup.r.o.warp_mode == ERTS_MULTI_TIME_WARP_MODE); - erts_os_times(&os_mtime, &os_stime); + os_times(&os_mtime, &os_stime); check_os_monotonic_time(esdp, os_mtime); @@ -792,7 +840,7 @@ init_check_time_correction(void *vesdp) old_mtime = ddp->intervals[0].time.mon; old_stime = ddp->intervals[0].time.sys; - erts_os_times(&mtime, &stime); + os_times(&mtime, &stime); check_os_monotonic_time((!vesdp ? erts_get_scheduler_data() @@ -841,7 +889,7 @@ finalize_corrected_time_offset(ErtsSystemTime *stimep) erts_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx); - erts_os_times(&os_mtime, stimep); + os_times(&os_mtime, stimep); ci = time_sup.inf.c.parmon.cdata.insts.curr; @@ -1015,6 +1063,17 @@ erts_init_time_sup(int time_correction, ErtsTimeWarpMode time_warp_mode) runtime_prev.data.user = 0; runtime_prev.data.sys = 0; +#ifdef ERTS_ENSURE_OS_MONOTONIC_TIME + if (!time_sup.r.o.os_monotonic_time_disable) { + time_sup.r.o.os_corrected_monotonic_time = 0; /* we don't trust it... */ + time_sup.r.o.os_monotonic_time_locked = !0; + erts_mtx_init(&time_sup.f.c.mtime_mtx, "ensure_os_monotonic_time", + NIL, (ERTS_LOCK_FLAGS_PROPERTY_STATIC + | ERTS_LOCK_FLAGS_CATEGORY_GENERIC)); + time_sup.f.c.last_delivered_mtime = erts_os_monotonic_time(); + } +#endif + time_sup.r.o.correction = time_correction; time_sup.r.o.warp_mode = time_warp_mode; @@ -1167,7 +1226,7 @@ erts_init_time_sup(int time_correction, ErtsTimeWarpMode time_warp_mode) ErtsMonotonicCorrectionData *cdatap; erts_rwmtx_opt_t rwmtx_opts = ERTS_RWMTX_OPT_DEFAULT_INITER; ErtsMonotonicTime offset; - erts_os_times(&time_sup.inf.c.minit, &time_sup.inf.c.sinit); + os_times(&time_sup.inf.c.minit, &time_sup.inf.c.sinit); time_sup.r.o.moffset = -1*time_sup.inf.c.minit; time_sup.r.o.moffset += ERTS_MONOTONIC_BEGIN; offset = time_sup.inf.c.sinit; @@ -2136,7 +2195,7 @@ erts_monotonic_time_source(struct process *c_p) Sint64 os_mtime = 0; #ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT if (!time_sup.r.o.os_monotonic_time_disable) - os_mtime = (Sint64) erts_os_monotonic_time(); + os_mtime = (Sint64) os_monotonic_time(); #endif bld_monotonic_time_source(NULL, &hsz, os_mtime); diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 1ffc7f5028..f9731f5396 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -720,6 +720,10 @@ extern char *erts_default_arg0; extern char os_type[]; +#if !defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) +# undef ERTS_ENSURE_OS_MONOTONIC_TIME +#endif + typedef struct { int have_os_monotonic_time; int have_corrected_os_monotonic_time; diff --git a/make/configure b/make/configure index c44049816c..c241dafa4e 100755 --- a/make/configure +++ b/make/configure @@ -767,6 +767,7 @@ enable_m64_build enable_m32_build enable_pie with_libatomic_ops +enable_ensure_os_monotonic_time enable_sanitizers enable_silent_rules ' @@ -1473,6 +1474,17 @@ Optional Features: --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc --enable-pie build position independent executables --disable-pie do no build position independent executables + --enable-ensure-os-monotonic-time + enable functionality ensuring the monotonicity of + monotonic timestamps delivered by the OS. When a + non-monotonic timestamp is detected, it will be + replaced by the last delivered monotonic timestamp + before being used by Erlang's time functionality. + Note that you do *not* want to enable this unless + the OS monotonic time source on the system fails to + produce monotonic timestamps. This since ensuring + the monotonicity of OS monotonic timestamps will + hurt scalability and performance of the system. --enable-sanitizers[=comma-separated list of sanitizers] Default=address,undefined --enable-silent-rules less verbose build output (undo: "make V=1") @@ -4650,6 +4662,12 @@ if test "${with_libatomic_ops+set}" = set; then : fi +# Check whether --enable-ensure-os-monotonic-time was given. +if test "${enable_ensure_os_monotonic_time+set}" = set; then : + enableval=$enable_ensure_os_monotonic_time; +fi + + # Check whether --enable-sanitizers was given. if test "${enable_sanitizers+set}" = set; then : diff --git a/make/configure.in b/make/configure.in index 660c51e363..83a24f12b6 100644 --- a/make/configure.in +++ b/make/configure.in @@ -368,6 +368,10 @@ AC_ARG_WITH(libatomic_ops, AS_HELP_STRING([--with-libatomic_ops=PATH], [specify and prefer usage of libatomic_ops in the ethread library])) +AC_ARG_ENABLE(ensure-os-monotonic-time, +AS_HELP_STRING([--enable-ensure-os-monotonic-time], + [enable functionality ensuring the monotonicity of monotonic timestamps delivered by the OS. When a non-monotonic timestamp is detected, it will be replaced by the last delivered monotonic timestamp before being used by Erlang's time functionality. Note that you do *not* want to enable this unless the OS monotonic time source on the system fails to produce monotonic timestamps. This since ensuring the monotonicity of OS monotonic timestamps will hurt scalability and performance of the system.])) + m4_define(DEFAULT_SANITIZERS, [address,undefined]) AC_ARG_ENABLE(sanitizers, AS_HELP_STRING( -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor