aboutsummaryrefslogtreecommitdiff
path: root/core/time
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2019-12-01 11:33:23 +0000
committerGitHub <noreply@github.com>2019-12-01 11:33:23 +0000
commit3fd5c3cd851d8f4dfd441141ca7e96889f069933 (patch)
tree67f47e79f5c5bb80a3ed1b1e9d79a61c08c0a29d /core/time
parent0c0c83ee295fe8787a4bdc8b826a5432abba2ca9 (diff)
parent99121d6ff2b02f3d16b791eb103bb9f9e8b96475 (diff)
Merge pull request #458 from Tetralux/linux-threads
Implement core:thread and core:sync on Unix using pthreads
Diffstat (limited to 'core/time')
-rw-r--r--core/time/time_darwin.odin56
-rw-r--r--core/time/time_linux.odin44
-rw-r--r--core/time/time_unix.odin80
-rw-r--r--core/time/time_windows.odin2
4 files changed, 80 insertions, 102 deletions
diff --git a/core/time/time_darwin.odin b/core/time/time_darwin.odin
deleted file mode 100644
index 91acd8ae7..000000000
--- a/core/time/time_darwin.odin
+++ /dev/null
@@ -1,56 +0,0 @@
-package time
-
-foreign import libc "system:c"
-
-TimeSpec :: struct {
- tv_sec : i64, /* seconds */
- tv_nsec : i64, /* nanoseconds */
-};
-
-CLOCK_SYSTEM :: 0;
-CLOCK_CALENDAR :: 1;
-
-IS_SUPPORTED :: true;
-
-foreign libc {
- @(link_name="clock_gettime") _clock_gettime :: proc(clock_id: u64, timespec: ^TimeSpec) ---;
- @(link_name="nanosleep") _nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> int ---;
- @(link_name="sleep") _sleep :: proc(seconds: u64) -> int ---;
-}
-
-clock_gettime :: proc(clock_id: u64) -> TimeSpec {
- ts : TimeSpec;
- _clock_gettime(clock_id, &ts);
- return ts;
-}
-
-now :: proc() -> Time {
-
- time_spec_now := clock_gettime(CLOCK_SYSTEM);
- ns := time_spec_now.tv_sec * 1e9 + time_spec_now.tv_nsec;
- return Time{_nsec=ns};
-}
-
-seconds_since_boot :: proc() -> f64 {
-
- ts_boottime := clock_gettime(CLOCK_SYSTEM);
- return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9;
-}
-
-sleep :: proc(d: Duration) {
-
- ds := duration_seconds(d);
- seconds := u64(ds);
- nanoseconds := i64((ds - f64(seconds)) * 1e9);
-
- if seconds > 0 do _sleep(seconds);
- if nanoseconds > 0 do nanosleep(nanoseconds);
-}
-
-nanosleep :: proc(nanoseconds: i64) -> int {
- assert(nanoseconds <= 999999999);
- requested, remaining : TimeSpec;
- requested = TimeSpec{tv_nsec = nanoseconds};
-
- return _nanosleep(&requested, &remaining);
-} \ No newline at end of file
diff --git a/core/time/time_linux.odin b/core/time/time_linux.odin
deleted file mode 100644
index d83d719fb..000000000
--- a/core/time/time_linux.odin
+++ /dev/null
@@ -1,44 +0,0 @@
-package time
-
-import "core:os";
-
-// NOTE(Jeroen): The times returned are in UTC
-IS_SUPPORTED :: true;
-
-now :: proc() -> Time {
-
- time_spec_now := os.clock_gettime(os.CLOCK_REALTIME);
- ns := time_spec_now.tv_sec * 1e9 + time_spec_now.tv_nsec;
- return Time{_nsec=ns};
-}
-
-boot_time :: proc() -> Time {
-
- ts_now := os.clock_gettime(os.CLOCK_REALTIME);
- ts_boottime := os.clock_gettime(os.CLOCK_BOOTTIME);
-
- ns := (ts_now.tv_sec - ts_boottime.tv_sec) * 1e9 + ts_now.tv_nsec - ts_boottime.tv_nsec;
- return Time{_nsec=ns};
-}
-
-seconds_since_boot :: proc() -> f64 {
-
- ts_boottime := os.clock_gettime(os.CLOCK_BOOTTIME);
- return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9;
-}
-
-sleep :: proc(d: Duration) {
-
- ds := duration_seconds(d);
- seconds := u64(ds);
- nanoseconds := i64((ds - f64(seconds)) * 1e9);
-
- if seconds > 0 do os.sleep(seconds);
- if nanoseconds > 0 do os.nanosleep(nanoseconds);
-}
-
-nanosleep :: proc(d: Duration) {
- // NOTE(Jeroen): os.nanosleep returns -1 on failure, 0 on success
- // duration needs to be [0, 999999999] nanoseconds.
- os.nanosleep(i64(d));
-}
diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin
new file mode 100644
index 000000000..28a6d6a9f
--- /dev/null
+++ b/core/time/time_unix.odin
@@ -0,0 +1,80 @@
+//+build linux, darwin
+package time
+
+IS_SUPPORTED :: true; // NOTE: Times on Darwin are UTC.
+
+foreign import libc "system:c"
+
+@(default_calling_convention="c")
+foreign libc {
+ @(link_name="clock_gettime") _unix_clock_gettime :: proc(clock_id: u64, timespec: ^TimeSpec) -> i32 ---;
+ @(link_name="sleep") _unix_sleep :: proc(seconds: u32) -> i32 ---;
+ @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> i32 ---;
+}
+
+TimeSpec :: struct {
+ tv_sec : i64, /* seconds */
+ tv_nsec : i64, /* nanoseconds */
+};
+
+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;
+
+
+clock_gettime :: proc(clock_id: u64) -> TimeSpec {
+ ts : TimeSpec; // NOTE(tetra): Do we need to initialize this?
+ _unix_clock_gettime(clock_id, &ts);
+ return ts;
+}
+
+now :: proc() -> Time {
+ time_spec_now := clock_gettime(CLOCK_REALTIME);
+ ns := time_spec_now.tv_sec * 1e9 + time_spec_now.tv_nsec;
+ return Time{_nsec=ns};
+}
+
+boot_time :: proc() -> Time {
+ ts_now := clock_gettime(CLOCK_REALTIME);
+ ts_boottime := clock_gettime(CLOCK_BOOTTIME);
+
+ ns := (ts_now.tv_sec - ts_boottime.tv_sec) * 1e9 + ts_now.tv_nsec - ts_boottime.tv_nsec;
+ return Time{_nsec=ns};
+}
+
+seconds_since_boot :: proc() -> f64 {
+ ts_boottime := clock_gettime(CLOCK_BOOTTIME);
+ return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9;
+}
+
+
+sleep :: proc(d: Duration) {
+ ds := duration_seconds(d);
+ seconds := u32(ds);
+ nanoseconds := i64((ds - f64(seconds)) * 1e9);
+
+ if seconds > 0 do _unix_sleep(seconds);
+ if nanoseconds > 0 do nanosleep(nanoseconds);
+}
+
+nanosleep :: proc(nanoseconds: i64) -> int {
+ // NOTE(tetra): Should we remove this assert? We are measuring nanoseconds after all...
+ assert(nanoseconds <= 999999999);
+
+ requested := TimeSpec{tv_nsec = nanoseconds};
+ remaining: TimeSpec; // NOTE(tetra): Do we need to initialize this?
+ return int(_unix_nanosleep(&requested, &remaining));
+} \ No newline at end of file
diff --git a/core/time/time_windows.odin b/core/time/time_windows.odin
index f6bfdd678..c1d766aee 100644
--- a/core/time/time_windows.odin
+++ b/core/time/time_windows.odin
@@ -17,8 +17,6 @@ now :: proc() -> Time {
return Time{_nsec=ns};
}
-
-
sleep :: proc(d: Duration) {
win32.sleep(u32(d/Millisecond));
}