File 8202-erts-Add-info-about-used-resolution-for-OS-monotonic.patch of Package erlang
From 0a1f990d8f9fc1ed948f938e3f9302bcb6c8e63e Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Fri, 5 Apr 2024 16:48:54 +0200
Subject: [PATCH 2/2] [erts] Add info about used resolution for OS monotonic
time
---
erts/doc/src/erlang.xml | 12 ++++++++++++
erts/emulator/beam/erl_time_sup.c | 13 +++++++++++--
erts/emulator/beam/sys.h | 1 +
erts/emulator/sys/win32/sys_time.c | 15 +++++++++++----
4 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index a5e4a3b331..51b4c4438e 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -10247,6 +10247,18 @@ Metadata = #{ pid => pid(),
however, know that the precision is not better than
<c>OsMonotonicTimeResolution</c>.</p>
</item>
+ <tag><c>{used_resolution, UsedOsMonotonicTimeResolution}</c></tag>
+ <item><p>
+ The OS monotonic time resolution used by the runtime system.
+ This is very often the same as <c>OsMonotonicTimeResolution</c>.
+ However, on some systems the resolution has to be reduced in
+ order to reliably produce monotonic timestamps. An example of
+ this is when <c>QueryPerformanceCounter()</c> is used as
+ OS monotonic time source on Windows. If such a reduction of
+ the resolution has been done,
+ <c>UsedOsMonotonicTimeResolution</c> will be smaller than
+ <c>OsMonotonicTimeResolution</c>.
+ </p></item>
<tag><c>{extended, Extended}</c></tag>
<item><p><c>Extended</c> equals <c>yes</c> if
the range of time values has been extended;
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 0e1d4b087f..abb945ebd2 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -93,6 +93,7 @@ struct time_sup_read_only__ {
char *os_monotonic_time_clock_id;
int os_monotonic_time_locked;
Uint64 os_monotonic_time_resolution;
+ Uint64 os_monotonic_time_used_resolution;
Uint64 os_monotonic_time_extended;
#endif
char *os_system_time_func;
@@ -934,6 +935,10 @@ void erts_init_sys_time_sup(void)
= sys_init_time_res.os_monotonic_time_info.locked_use;
time_sup.r.o.os_monotonic_time_resolution
= sys_init_time_res.os_monotonic_time_info.resolution;
+ time_sup.r.o.os_monotonic_time_used_resolution
+ = (!sys_init_time_res.os_monotonic_time_info.used_resolution
+ ? sys_init_time_res.os_monotonic_time_info.resolution
+ : sys_init_time_res.os_monotonic_time_info.used_resolution);
time_sup.r.o.os_monotonic_time_extended
= sys_init_time_res.os_monotonic_time_info.extended;
#endif
@@ -2044,8 +2049,8 @@ bld_monotonic_time_source(Uint **hpp, Uint *szp, Sint64 os_mtime)
return NIL;
#else
int i = 0;
- Eterm k[6];
- Eterm v[6];
+ Eterm k[7];
+ Eterm v[7];
if (time_sup.r.o.os_monotonic_time_disable)
return NIL;
@@ -2064,6 +2069,10 @@ bld_monotonic_time_source(Uint **hpp, Uint *szp, Sint64 os_mtime)
v[i++] = erts_bld_uint64(hpp, szp,
time_sup.r.o.os_monotonic_time_resolution);
+ k[i] = erts_bld_atom(hpp, szp, "used_resolution");
+ v[i++] = erts_bld_uint64(hpp, szp,
+ time_sup.r.o.os_monotonic_time_used_resolution);
+
k[i] = erts_bld_atom(hpp, szp, "extended");
v[i++] = time_sup.r.o.os_monotonic_time_extended ? am_yes : am_no;
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 1ffc7f5028..6a5908d51b 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -727,6 +727,7 @@ typedef struct {
ErtsMonotonicTime sys_clock_resolution;
struct {
Uint64 resolution;
+ Uint64 used_resolution;
char *func;
char *clock_id;
int locked_use;
diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c
index 1febfee829..81e621eb2e 100644
--- a/erts/emulator/sys/win32/sys_time.c
+++ b/erts/emulator/sys/win32/sys_time.c
@@ -29,8 +29,12 @@
#include "erl_os_monotonic_time_extender.h"
#include "erl_time.h"
-/* Need to look more closely at qpc before use... */
-#define ERTS_DISABLE_USE_OF_QPC_FOR_MONOTONIC_TIME 1
+/*
+ * How much to reduce the resolution of the by QueryPerformanceCounter()
+ * returned values in order to make them monotonic...
+ */
+#define ERTS_WIN_QPC_SKIP_BITS 10
+#define ERTS_WIN_QPC_SKIP_MASK ((1 << ERTS_WIN_QPC_SKIP_BITS) - 1)
#define LL_LITERAL(X) ERTS_I64_LITERAL(X)
@@ -159,9 +163,9 @@ os_monotonic_time_qpc(void)
if (!(*internal_state.r.o.pQueryPerformanceCounter)(&pc))
erts_exit(ERTS_ABORT_EXIT, "QueryPerformanceCounter() failed\n");
temp = (ErtsMonotonicTime) pc.QuadPart;
- } while(!(temp & SKIP));
+ } while(!(temp & ERTS_WIN_QPC_SKIP_MASK));
- return temp & (ERTS_I64_LITERAL(0xFFFFFFFFFFFFFFFF)-SKIP);
+ return temp & (ERTS_I64_LITERAL(0xFFFFFFFFFFFFFFFF)-ERTS_WIN_QPC_SKIP_MASK);
}
static void
@@ -381,6 +385,9 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
time_unit = (ErtsMonotonicTime) pf.QuadPart;
internal_state.r.o.using_get_tick_count_time_unit = 0;
init_resp->os_monotonic_time_info.resolution = time_unit;
+ /* We reduce the used resolution in order to make it monotonic... */
+ init_resp->os_monotonic_time_info.used_resolution
+ = time_unit >> ERTS_WIN_QPC_SKIP_BITS;
os_mtime_func = os_monotonic_time_qpc;
os_times_func = os_times_qpc;
}
--
2.35.3