Blender V5.0
time.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_time.h"
10
11#ifdef WIN32
12
13# include <cmath>
14# include <cstdio>
15
16# define WIN32_LEAN_AND_MEAN
17# include <windows.h>
18
19/* timeapi.h needs to be included after windows.h. */
20# include <timeapi.h>
21
23{
24 static int hasperfcounter = -1; /* (-1 == unknown) */
25 static double perffreq;
26
27 if (hasperfcounter == -1) {
28 __int64 ifreq;
29 hasperfcounter = QueryPerformanceFrequency((LARGE_INTEGER *)&ifreq);
30 perffreq = double(ifreq);
31 }
32
33 if (hasperfcounter) {
34 __int64 count;
35
36 QueryPerformanceCounter((LARGE_INTEGER *)&count);
37
38 return count / perffreq;
39 }
40 else {
41 static double accum = 0.0;
42 static int ltick = 0;
43 int ntick = GetTickCount();
44
45 if (ntick < ltick) {
46 accum += (0xFFFFFFFF - ltick + ntick) / 1000.0;
47 }
48 else {
49 accum += (ntick - ltick) / 1000.0;
50 }
51
52 ltick = ntick;
53 return accum;
54 }
55}
56
58{
59 return (long int)BLI_time_now_seconds();
60}
61
62void BLI_time_sleep_ms(int ms)
63{
64 Sleep(ms);
65}
66
68{
69 /* Prefer thread-safety over caching the timer with a static variable. According to
70 * https://github.com/rust-lang/rust/pull/116461/files, this costs only approximately 2000ns. */
71 HANDLE timerHandle = CreateWaitableTimerExW(
72 nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
73 if (!timerHandle) {
74 if (GetLastError() == ERROR_INVALID_PARAMETER) {
75 /* CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is only supported since Windows 10, version 1803. */
76 DWORD duration_ms = DWORD(std::ceil(double(us) / 1000.0));
77 Sleep(duration_ms);
78 }
79 else {
80 fprintf(stderr,
81 "BLI_time_sleep_precise_us: CreateWaitableTimerExW failed: %d\n",
82 GetLastError());
83 }
84 return;
85 }
86
87 /* Wait time is specified in 100 nanosecond intervals. */
88 LARGE_INTEGER wait_time;
89 wait_time.QuadPart = -us * 10;
90 if (!SetWaitableTimer(timerHandle, &wait_time, 0, nullptr, nullptr, 0)) {
91 fprintf(stderr, "BLI_time_sleep_precise_us: SetWaitableTimer failed: %d\n", GetLastError());
92 CloseHandle(timerHandle);
93 return;
94 }
95
96 if (WaitForSingleObject(timerHandle, INFINITE) != WAIT_OBJECT_0) {
97 fprintf(stderr, "BLI_time_sleep_precise_us: WaitForSingleObject failed: %d\n", GetLastError());
98 CloseHandle(timerHandle);
99 return;
100 }
101
102 CloseHandle(timerHandle);
103}
104
105#else
106
107# include <chrono>
108# include <thread>
109
110# include <sys/time.h>
111# include <unistd.h>
112
114{
115 timeval tv;
116 struct timezone tz;
117
118 gettimeofday(&tv, &tz);
119
120 return (double(tv.tv_sec) + tv.tv_usec / 1000000.0);
121}
122
124{
125 timeval tv;
126 struct timezone tz;
127
128 gettimeofday(&tv, &tz);
129
130 return tv.tv_sec;
131}
132
134{
135 if (ms >= 1000) {
136 sleep(ms / 1000);
137 ms = (ms % 1000);
138 }
139
140 usleep(ms * 1000);
141}
142
144{
145 std::this_thread::sleep_for(std::chrono::microseconds(us));
146}
147
148#endif
Platform independent time functions.
int count
void BLI_time_sleep_ms(int ms)
Definition time.cc:133
double BLI_time_now_seconds()
Definition time.cc:113
long int BLI_time_now_seconds_i()
Definition time.cc:123
void BLI_time_sleep_precise_us(int us)
Definition time.cc:143