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