Skip to content

Commit a333b91

Browse files
committed
linux/aarch64 Now() should be actually_monotonic()
While issues have been seen on arm64 platforms the Arm architecture requires that the counter monotonically increases and that it must provide a uniform view of system time (e.g. it must not be possible for a core to receive a message from another core with a time stamp and observe time going backwards (ARM DDI 0487G.b D11.1.2). While there have been a few 64bit SoCs that have bugs (#49281, #56940) which cause time to not monotonically increase, these have been fixed in the Linux kernel and we shouldn't penalize all Arm SoCs for those who refuse to update their kernels: SUN50I_ERRATUM_UNKNOWN1 - Allwinner A64 / Pine A64 - fixed in 5.1 FSL_ERRATUM_A008585 - Freescale LS2080A/LS1043A - fixed in 4.10 HISILICON_ERRATUM_161010101 - Hisilicon 1610 - fixed in 4.11 ARM64_ERRATUM_858921 - Cortex A73 - fixed in 4.12 255a3f3 std: Force `Instant::now()` to be monotonic added a mutex to work around this problem and a small test program using glommio shows the majority of time spent acquiring and releasing this Mutex. 3914a7b tries to improve this, but actually makes it worse on big systems as for 128b atomics a ldxp/stxp pair (and successful loop) is required which is expensive as a lock and because of how the load/store-exclusives scale on large Arm systems is both unfair to threads and tends to go backwards in performance.
1 parent 72a51c3 commit a333b91

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

library/std/src/sys/unix/time.rs

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ mod inner {
303303
pub fn actually_monotonic() -> bool {
304304
(cfg!(target_os = "linux") && cfg!(target_arch = "x86_64"))
305305
|| (cfg!(target_os = "linux") && cfg!(target_arch = "x86"))
306+
|| (cfg!(target_os = "linux") && cfg!(target_arch = "aarch64"))
306307
|| cfg!(target_os = "fuchsia")
307308
}
308309

library/std/src/time.rs

+14
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ impl Instant {
263263
//
264264
// To hopefully mitigate the impact of this, a few platforms are
265265
// excluded as "these at least haven't gone backwards yet".
266+
//
267+
// While issues have been seen on arm64 platforms the Arm architecture
268+
// requires that the counter monotonically increases and that it must
269+
// provide a uniform view of system time (e.g. it must not be possible
270+
// for a core to recieve a message from another core with a time stamp
271+
// and observe time going backwards (ARM DDI 0487G.b D11.1.2). While
272+
// there have been a few 64bit SoCs that have bugs which cause time to
273+
// not monoticially increase, these have been fixed in the Linux kernel
274+
// and we shouldn't penalize all Arm SoCs for those who refuse to
275+
// update their kernels:
276+
// SUN50I_ERRATUM_UNKNOWN1 - Allwinner A64 / Pine A64 - fixed in 5.1
277+
// FSL_ERRATUM_A008585 - Freescale LS2080A/LS1043A - fixed in 4.10
278+
// HISILICON_ERRATUM_161010101 - Hisilicon 1610 - fixed in 4.11
279+
// ARM64_ERRATUM_858921 - Cortex A73 - fixed in 4.12
266280
if time::Instant::actually_monotonic() {
267281
return Instant(os_now);
268282
}

0 commit comments

Comments
 (0)