11#if !defined(PSNIP_CLOCK_H)
16#if !defined(psnip_uint64_t) || !defined(psnip_int32_t) || \
17 !defined(psnip_uint32_t) || !defined(psnip_int32_t)
19# if !defined(psnip_int64_t)
20# define psnip_int64_t int64_t
22# if !defined(psnip_uint64_t)
23# define psnip_uint64_t uint64_t
25# if !defined(psnip_int32_t)
26# define psnip_int32_t int32_t
28# if !defined(psnip_uint32_t)
29# define psnip_uint32_t uint32_t
33#if !defined(PSNIP_CLOCK_STATIC_INLINE)
35# define PSNIP_CLOCK__COMPILER_ATTRIBUTES __attribute__((__unused__))
37# define PSNIP_CLOCK__COMPILER_ATTRIBUTES
40# define PSNIP_CLOCK__FUNCTION PSNIP_CLOCK__COMPILER_ATTRIBUTES static
66#define PSNIP_CLOCK_METHOD_CLOCK_GETTIME 1
67#define PSNIP_CLOCK_METHOD_TIME 2
68#define PSNIP_CLOCK_METHOD_GETTIMEOFDAY 3
69#define PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER 4
70#define PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME 5
71#define PSNIP_CLOCK_METHOD_CLOCK 6
72#define PSNIP_CLOCK_METHOD_GETPROCESSTIMES 7
73#define PSNIP_CLOCK_METHOD_GETRUSAGE 8
74#define PSNIP_CLOCK_METHOD_GETSYSTEMTIMEPRECISEASFILETIME 9
75#define PSNIP_CLOCK_METHOD_GETTICKCOUNT64 10
79#if defined(HEDLEY_UNREACHABLE)
80# define PSNIP_CLOCK_UNREACHABLE() HEDLEY_UNREACHABLE()
82# define PSNIP_CLOCK_UNREACHABLE() assert(0)
93#if defined(__unix__) || defined(__unix) || defined(__linux__)
98#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
102 (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17))) || \
103 (defined(__FreeBSD__)) || \
104 !defined(PSNIP_CLOCK_NO_LIBRT)
109# if _POSIX_C_SOURCE >= 199309L
110# define PSNIP_CLOCK_HAVE_CLOCK_GETTIME
116# if !defined(PSNIP_CLOCK_CPU_METHOD)
117# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_GETPROCESSTIMES
119# if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
120# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER
124#if defined(__MACH__) && !defined(__gnu_hurd__)
125# if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
126# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME
130#if defined(PSNIP_CLOCK_HAVE_CLOCK_GETTIME)
132# if !defined(PSNIP_CLOCK_WALL_METHOD)
133# if defined(CLOCK_REALTIME_PRECISE)
134# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
135# define PSNIP_CLOCK_CLOCK_GETTIME_WALL CLOCK_REALTIME_PRECISE
136# elif !defined(__sun)
137# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
138# define PSNIP_CLOCK_CLOCK_GETTIME_WALL CLOCK_REALTIME
141# if !defined(PSNIP_CLOCK_CPU_METHOD)
142# if defined(_POSIX_CPUTIME) || defined(CLOCK_PROCESS_CPUTIME_ID)
143# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
144# define PSNIP_CLOCK_CLOCK_GETTIME_CPU CLOCK_PROCESS_CPUTIME_ID
145# elif defined(CLOCK_VIRTUAL)
146# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
147# define PSNIP_CLOCK_CLOCK_GETTIME_CPU CLOCK_VIRTUAL
150# if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
151# if defined(_POSIX_MONOTONIC_CLOCK) || defined(CLOCK_MONOTONIC)
152# define PSNIP_CLOCK_MONOTONIC_METHOD PSNIP_CLOCK_METHOD_CLOCK_GETTIME
153# define PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC CLOCK_MONOTONIC
158#if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200112L)
159# if !defined(PSNIP_CLOCK_WALL_METHOD)
160# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_GETTIMEOFDAY
164#if !defined(PSNIP_CLOCK_WALL_METHOD)
165# define PSNIP_CLOCK_WALL_METHOD PSNIP_CLOCK_METHOD_TIME
168#if !defined(PSNIP_CLOCK_CPU_METHOD)
169# define PSNIP_CLOCK_CPU_METHOD PSNIP_CLOCK_METHOD_CLOCK
173#if !defined(PSNIP_CLOCK_MONOTONIC_METHOD) && defined(PSNIP_CLOCK_REQUIRE_MONOTONIC)
174# error No monotonic clock found.
180 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
181 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
182 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
183 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \
184 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \
185 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK)) || \
186 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_TIME)) || \
187 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME)) || \
188 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_TIME))
193 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) || \
194 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY)) || \
195 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY))
196# include <sys/time.h>
200 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \
201 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \
202 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES)) || \
203 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) || \
204 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64)) || \
205 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64))
210 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) || \
211 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE)) || \
212 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE))
213# include <sys/time.h>
214# include <sys/resource.h>
218 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) || \
219 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME)) || \
220 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME))
221# include <CoreServices/CoreServices.h>
222# include <mach/mach.h>
223# include <mach/mach_time.h>
228#define PSNIP_CLOCK_NSEC_PER_SEC ((psnip_uint32_t) (1000000000ULL))
231 (defined(PSNIP_CLOCK_CPU_METHOD) && (PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
232 (defined(PSNIP_CLOCK_WALL_METHOD) && (PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME)) || \
233 (defined(PSNIP_CLOCK_MONOTONIC_METHOD) && (PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME))
235psnip_clock__clock_getres (clockid_t clk_id) {
239 r = clock_getres(clk_id, &res);
250 if (clock_gettime(clk_id, &ts) != 0)
261psnip_clock_wall_get_precision (
void) {
262#if !defined(PSNIP_CLOCK_WALL_METHOD)
264#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
265 return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_WALL);
266#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY
268#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME
279#if !defined(PSNIP_CLOCK_WALL_METHOD)
281#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
282 return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_WALL, res);
283#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_TIME
284 res->
seconds = (uint64_t) time(NULL);
286#elif defined(PSNIP_CLOCK_WALL_METHOD) && PSNIP_CLOCK_WALL_METHOD == PSNIP_CLOCK_METHOD_GETTIMEOFDAY
289 if (gettimeofday(&tv, NULL) != 0)
302psnip_clock_cpu_get_precision (
void) {
303#if !defined(PSNIP_CLOCK_CPU_METHOD)
305#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
306 return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_CPU);
307#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK
308 return CLOCKS_PER_SEC;
309#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES
318#if !defined(PSNIP_CLOCK_CPU_METHOD)
321#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
322 return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_CPU, res);
323#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_CLOCK
325 if (t == ((clock_t) -1))
327 res->
seconds = t / CLOCKS_PER_SEC;
329#elif defined(PSNIP_CLOCK_CPU_METHOD) && PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETPROCESSTIMES
330 FILETIME CreationTime, ExitTime, KernelTime, UserTime;
331 LARGE_INTEGER date, adjust;
333 if (!GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime))
337 date.HighPart = UserTime.dwHighDateTime;
338 date.LowPart = UserTime.dwLowDateTime;
339 adjust.QuadPart = 11644473600000 * 10000;
340 date.QuadPart -= adjust.QuadPart;
342 res->
seconds = date.QuadPart / 10000000;
344#elif PSNIP_CLOCK_CPU_METHOD == PSNIP_CLOCK_METHOD_GETRUSAGE
346 if (getrusage(RUSAGE_SELF, &usage) != 0)
349 res->
seconds = usage.ru_utime.tv_sec;
360psnip_clock_monotonic_get_precision (
void) {
361#if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
363#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
364 return psnip_clock__clock_getres(PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC);
365#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME
366 static mach_timebase_info_data_t tbi = { 0, };
368 mach_timebase_info(&tbi);
370#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64
372#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER
373 LARGE_INTEGER Frequency;
374 QueryPerformanceFrequency(&Frequency);
383#if !defined(PSNIP_CLOCK_MONOTONIC_METHOD)
386#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_CLOCK_GETTIME
387 return psnip_clock__clock_gettime(PSNIP_CLOCK_CLOCK_GETTIME_MONOTONIC, res);
388#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_MACH_ABSOLUTE_TIME
390 static mach_timebase_info_data_t tbi = { 0, };
392 mach_timebase_info(&tbi);
396#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_QUERYPERFORMANCECOUNTER
398 if (QueryPerformanceCounter(&t) == 0)
401 QueryPerformanceFrequency(&f);
402 res->
seconds = t.QuadPart / f.QuadPart;
408#elif defined(PSNIP_CLOCK_MONOTONIC_METHOD) && PSNIP_CLOCK_MONOTONIC_METHOD == PSNIP_CLOCK_METHOD_GETTICKCOUNT64
409 const ULONGLONG msec = GetTickCount64();
433 switch (clock_type) {
435 return psnip_clock_monotonic_get_precision ();
437 return psnip_clock_cpu_get_precision ();
439 return psnip_clock_wall_get_precision ();
452 switch (clock_type) {
454 return psnip_clock_monotonic_get_time (res);
456 return psnip_clock_cpu_get_time (res);
458 return psnip_clock_wall_get_time (res);
#define psnip_uint64_t
Definition: clock.h:23
#define PSNIP_CLOCK__FUNCTION
Definition: clock.h:40
#define psnip_uint32_t
Definition: clock.h:29
#define PSNIP_CLOCK_NSEC_PER_SEC
Definition: clock.h:228
#define PSNIP_CLOCK_UNREACHABLE()
Definition: clock.h:82
PsnipClockType
Definition: clock.h:43
@ PSNIP_CLOCK_TYPE_WALL
Definition: clock.h:48
@ PSNIP_CLOCK_TYPE_CPU
Definition: clock.h:52
@ PSNIP_CLOCK_TYPE_MONOTONIC
Definition: clock.h:56
uint64_t seconds
Definition: clock.h:60
uint64_t nanoseconds
Definition: clock.h:61