blob: 241eaef698f9e0086c6605f5ddd6f2cd1d4cb192 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#ifndef PURE_WAIT_H
#define PURE_WAIT_H
/* Timed waits that count on the monotonic clock. A deadline read from the
* wall clock moves when the clock is set (by a person, or NTP): set back an
* hour, a wait begun before lasts an hour more; set forward, it ends at once.
* A condition made by pure_cond_monotonic waits until a time pure_wait_until
* gives, and neither happens. (macOS has no clock for conditions: there both
* keep to the wall clock.) */
#include <pthread.h>
#include <time.h>
#ifdef __APPLE__
#define PURE_WAIT_CLOCK CLOCK_REALTIME
#else
#define PURE_WAIT_CLOCK CLOCK_MONOTONIC
#endif
static inline int pure_cond_monotonic(pthread_cond_t *cond) {
#ifdef __APPLE__
return pthread_cond_init(cond, NULL);
#else
pthread_condattr_t attr;
int result = pthread_condattr_init(&attr);
if (result) return result;
result = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
if (!result) result = pthread_cond_init(cond, &attr);
pthread_condattr_destroy(&attr);
return result;
#endif
}
/* The time ns from now, on the clock pure_cond_monotonic's conditions wait on. */
static inline struct timespec pure_wait_until(long long ns) {
struct timespec t;
clock_gettime(PURE_WAIT_CLOCK, &t);
t.tv_sec += (time_t)(ns / 1000000000);
t.tv_nsec += (long)(ns % 1000000000);
if (t.tv_nsec >= 1000000000) {
++t.tv_sec;
t.tv_nsec -= 1000000000;
}
return t;
}
#endif
|