aboutsummaryrefslogtreecommitdiff
path: root/core/sys
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-05-12 15:47:24 +0100
committergingerBill <bill@gingerbill.org>2022-05-12 15:47:24 +0100
commitf002857edce5ea53561608fa555bbbd94b7fa42a (patch)
tree72706817d402070beecfa6d777e52d33b1e2f3c5 /core/sys
parent97739da85a9812e37d1c349eb36f899b157dc8f5 (diff)
Clean up `core:time` to be consistent across all platforms
Diffstat (limited to 'core/sys')
-rw-r--r--core/sys/unix/pthread_unix.odin5
-rw-r--r--core/sys/unix/time_unix.odin83
2 files changed, 85 insertions, 3 deletions
diff --git a/core/sys/unix/pthread_unix.odin b/core/sys/unix/pthread_unix.odin
index 62e3701ab..8bf397647 100644
--- a/core/sys/unix/pthread_unix.odin
+++ b/core/sys/unix/pthread_unix.odin
@@ -4,7 +4,6 @@ package unix
foreign import "system:pthread"
import "core:c"
-import "core:time"
//
// On success, these functions return 0.
@@ -72,7 +71,7 @@ foreign pthread {
// assumes the mutex is pre-locked
pthread_cond_wait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t) -> c.int ---
- pthread_cond_timedwait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t, timeout: ^time.TimeSpec) -> c.int ---
+ pthread_cond_timedwait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int ---
pthread_condattr_init :: proc(attrs: ^pthread_condattr_t) -> c.int ---
pthread_condattr_destroy :: proc(attrs: ^pthread_condattr_t) -> c.int ---
@@ -95,7 +94,7 @@ foreign pthread {
pthread_mutex_lock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
- pthread_mutex_timedlock :: proc(mutex: ^pthread_mutex_t, timeout: ^time.TimeSpec) -> c.int ---
+ pthread_mutex_timedlock :: proc(mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int ---
pthread_mutex_unlock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
diff --git a/core/sys/unix/time_unix.odin b/core/sys/unix/time_unix.odin
new file mode 100644
index 000000000..d9452c216
--- /dev/null
+++ b/core/sys/unix/time_unix.odin
@@ -0,0 +1,83 @@
+//+build linux, darwin, freebsd, openbsd
+package unix
+
+when ODIN_OS == .Darwin {
+ foreign import libc "System.framework"
+} else {
+ foreign import libc "system:c"
+}
+
+@(default_calling_convention="c")
+foreign libc {
+ clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> i32 ---
+ sleep :: proc(seconds: u32) -> i32 ---
+ nanosleep :: proc(requested, remaining: ^timespec) -> i32 ---
+}
+
+foreign import "system:pthread"
+
+import "core:c"
+
+@(private="file")
+@(default_calling_convention="c")
+foreign pthread {
+ sched_yield :: proc() -> c.int ---
+}
+
+timespec :: struct {
+ tv_sec: i64, // seconds
+ tv_nsec: i64, // nanoseconds
+}
+
+when ODIN_OS == .OpenBSD {
+ CLOCK_REALTIME :: 0
+ CLOCK_PROCESS_CPUTIME_ID :: 2
+ CLOCK_MONOTONIC :: 3
+ CLOCK_THREAD_CPUTIME_ID :: 4
+ CLOCK_UPTIME :: 5
+ CLOCK_BOOTTIME :: 6
+
+ // CLOCK_MONOTONIC_RAW doesn't exist, use CLOCK_MONOTONIC
+ CLOCK_MONOTONIC_RAW :: CLOCK_MONOTONIC
+} else {
+ CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time.
+ CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep.
+ CLOCK_PROCESS_CPUTIME_ID :: 2
+ CLOCK_THREAD_CPUTIME_ID :: 3
+ CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP.
+ CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained."
+ CLOCK_MONOTONIC_COARSE :: 6
+ CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep.
+ CLOCK_REALTIME_ALARM :: 8
+ CLOCK_BOOTTIME_ALARM :: 9
+}
+
+// TODO(tetra, 2019-11-05): The original implementation of this package for Darwin used this constants.
+// I do not know if Darwin programmers are used to the existance of these constants or not, so
+// I'm leaving aliases to them for now.
+CLOCK_SYSTEM :: CLOCK_REALTIME
+CLOCK_CALENDAR :: CLOCK_MONOTONIC
+
+boot_time_in_nanoseconds :: proc "c" () -> i64 {
+ ts_now, ts_boottime: timespec
+ clock_gettime(CLOCK_REALTIME, &ts_now)
+ clock_gettime(CLOCK_BOOTTIME, &ts_boottime)
+
+ ns := (ts_now.tv_sec - ts_boottime.tv_sec) * 1e9 + ts_now.tv_nsec - ts_boottime.tv_nsec
+ return i64(ns)
+}
+
+seconds_since_boot :: proc "c" () -> f64 {
+ ts_boottime: timespec
+ clock_gettime(CLOCK_BOOTTIME, &ts_boottime)
+ return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9
+}
+
+
+inline_nanosleep :: proc "c" (nanoseconds: i64) -> (remaining: timespec, res: i32) {
+ s, ns := nanoseconds / 1e9, nanoseconds % 1e9
+ requested := timespec{tv_sec=s, tv_nsec=ns}
+ res = nanosleep(&requested, &remaining)
+ return
+}
+