From 0a0440a6e869e8d8791608f14fb55f37f323a23e Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 16 Apr 2022 14:08:37 +0300 Subject: [PATCH] time: yield accurate_sleep instead of relaxing the cpu --- core/time/time.odin | 10 ++++++++-- core/time/time_unix.odin | 6 ++++++ core/time/time_windows.odin | 4 ++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/core/time/time.odin b/core/time/time.odin index 7056f83f8..f2e974647 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -213,6 +213,10 @@ time_add :: proc(t: Time, d: Duration) -> Time { return Time{t._nsec + i64(d)} } +yield :: proc "contextless" () { + _yield() +} + // Accurate sleep borrowed from: https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/ accurate_sleep :: proc(d: Duration) { to_sleep, estimate, mean, m2, count: Duration @@ -240,8 +244,10 @@ accurate_sleep :: proc(d: Duration) { start := tick_now() for to_sleep > tick_since(start) { - intrinsics.cpu_relax() // prevent the spinlock from taking the thread hostage, still accurate enough - // NOTE: it is possible that sometimes cpu can relax a bit too much, in that case it should spinlock freely for a while (TODO) + // prevent the spinlock from taking the thread hostage, still accurate enough + yield() + // NOTE: it might be possible that it yields for too long, in that case it should spinlock freely for a while + // TODO: needs actual testing done to check if that's the case } } diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index 37fc1fd3e..db15a824a 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -1,6 +1,8 @@ //+build linux, darwin, freebsd, openbsd package time +import "core:sys/unix" + IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. when ODIN_OS == .Darwin { @@ -17,6 +19,10 @@ foreign libc { @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> i32 --- } +_yield :: proc "contextless" () { + unix.sched_yield() +} + TimeSpec :: struct { tv_sec : i64, /* seconds */ tv_nsec : i64, /* nanoseconds */ diff --git a/core/time/time_windows.odin b/core/time/time_windows.odin index 0fb9eaa0f..397741126 100644 --- a/core/time/time_windows.odin +++ b/core/time/time_windows.odin @@ -35,3 +35,7 @@ _tick_now :: proc "contextless" () -> Tick { _nsec := mul_div_u64(i64(now), 1e9, i64(qpc_frequency)) return Tick{_nsec = _nsec} } + +_yield :: proc "contextless" () { + win32.SwitchToThread() +}