aboutsummaryrefslogtreecommitdiff
path: root/Spear/Sys/Timer/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'Spear/Sys/Timer/timer.c')
-rw-r--r--Spear/Sys/Timer/timer.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/Spear/Sys/Timer/timer.c b/Spear/Sys/Timer/timer.c
new file mode 100644
index 0000000..8487f48
--- /dev/null
+++ b/Spear/Sys/Timer/timer.c
@@ -0,0 +1,101 @@
1#include "timer.h"
2
3#include <stdlib.h>
4#ifdef _WIN32
5#define WIN32_LEAN_AND_MEAN
6#include <Windows.h>
7#endif
8
9#ifdef _WIN32
10static const int64_t microseconds = 1000000;
11#endif
12static const int64_t nanoseconds = 1000000000;
13
14#ifdef _WIN32
15static double seconds_per_count;
16#endif
17
18static void timer_initialise() {
19#ifdef _WIN32
20 __int64 counts_per_sec;
21 QueryPerformanceFrequency((LARGE_INTEGER*)&counts_per_sec);
22 seconds_per_count = 1.0 / (double)counts_per_sec;
23#endif
24}
25
26void timer_make(Timer* timer) {
27 timer_initialise();
28 *timer = (Timer){0};
29 timer_start(timer);
30}
31
32void timer_start(Timer* timer) {
33 time_now(&timer->start_time);
34 timer->last_tick = timer->start_time;
35 timer->running_time = 0;
36 timer->delta_time = 0;
37}
38
39void timer_tick(Timer* timer) {
40 time_point this_tick;
41 time_now(&this_tick);
42 timer->running_time = time_diff(&timer->start_time, &this_tick);
43 timer->delta_time = time_diff(&timer->last_tick, &this_tick);
44 timer->last_tick = this_tick;
45}
46
47void time_now(time_point* t) {
48#ifdef _WIN32
49 QueryPerformanceCounter((LARGE_INTEGER*)t);
50#else
51 clock_gettime(CLOCK_REALTIME, t);
52#endif
53}
54
55time_delta time_diff(time_point* start, time_point* end) {
56#ifdef _WIN32
57 // Force nonnegative. The DXSDK's CDXUTTimer mentions that if the
58 // processor goes into a power save mode or we get shuffled to
59 // another processor, then the delta time can be negative.
60 return std::max(0, *end - *start);
61#else
62 return (end->tv_sec - start->tv_sec) * 1e9 + (end->tv_nsec - start->tv_nsec);
63#endif
64}
65
66double time_delta_to_sec(time_delta dt) {
67#ifdef _WIN32
68 return (double)dt * seconds_per_count;
69#else
70 return (double)dt * 1.0e-9;
71#endif
72}
73
74time_delta sec_to_time_delta(double seconds) {
75#ifdef _WIN32
76 return (time_delta)(seconds / seconds_per_count);
77#else
78 return (time_delta)(seconds * 1.0e9);
79#endif
80}
81
82uint64_t time_point_to_ns(time_point* t) {
83#ifdef _WIN32
84 return (uint64_t)((double)*t * seconds_per_count * 1.0e+9);
85#else
86 return (uint64_t)t->tv_sec * 1e+9 + (uint64_t)t->tv_nsec;
87#endif
88}
89
90void time_sleep(time_delta dt) {
91#ifdef _WIN32
92 const int64_t ms = dt / microseconds;
93 Sleep((DWORD)(ms));
94#else
95 const int64_t sec = dt / nanoseconds;
96 struct timespec ts;
97 ts.tv_sec = (long)sec;
98 ts.tv_nsec = (long)(dt % nanoseconds);
99 nanosleep(&ts, NULL);
100#endif
101}