123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- //+build linux, darwin, freebsd, openbsd, haiku
- package unix
- when ODIN_OS == .Darwin {
- foreign import libc "system:System.framework"
- } else {
- foreign import libc "system:c"
- }
- import "core:c"
- @(default_calling_convention="c")
- foreign libc {
- clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> c.int ---
- sleep :: proc(seconds: c.uint) -> c.int ---
- nanosleep :: proc(requested, remaining: ^timespec) -> 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
- }
|