summaryrefslogtreecommitdiffstats
path: root/osdep/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'osdep/timer.c')
-rw-r--r--osdep/timer.c66
1 files changed, 63 insertions, 3 deletions
diff --git a/osdep/timer.c b/osdep/timer.c
index 4f506b3d46..de37653a67 100644
--- a/osdep/timer.c
+++ b/osdep/timer.c
@@ -17,9 +17,15 @@
#include <stdlib.h>
#include <pthread.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <assert.h>
-#include "timer.h"
+#include "common/common.h"
#include "common/msg.h"
+#include "timer.h"
static uint64_t raw_time_offset;
pthread_once_t timer_init_once = PTHREAD_ONCE_INIT;
@@ -60,21 +66,75 @@ int64_t mp_time_relative_us(int64_t *t)
return r;
}
+int64_t mp_add_timeout(int64_t time_us, double timeout_sec)
+{
+ assert(time_us > 0); // mp_time_us() returns strictly positive values
+ double t = timeout_sec * 1000 * 1000;
+ if (t >= (double)(INT64_MAX - time_us))
+ return INT64_MAX;
+ if (t <= (double)time_us)
+ return 1;
+ return time_us + (int64_t)t;
+}
+
+static void get_realtime(struct timespec *out_ts)
+{
+#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
+ clock_gettime(CLOCK_REALTIME, out_ts);
+#else
+ // OSX
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ out_ts->tv_sec = tv.tv_sec;
+ out_ts->tv_nsec = tv.tv_usec * 1000UL;
+#endif
+}
+
+struct timespec mp_time_us_to_timespec(int64_t time_us)
+{
+ struct timespec ts;
+ get_realtime(&ts);
+ // We don't know what time source mp_time_us() uses, but usually it's not
+ // CLOCK_REALTIME - so we have to remap the times.
+ int64_t unow = mp_time_us();
+ int64_t diff_us = time_us - unow;
+ long diff_secs = diff_us / (1000L * 1000L);
+ unsigned long diff_nsecs = (diff_us - diff_secs * (1000L * 1000L)) * 1000UL;
+ if (diff_nsecs + ts.tv_nsec >= 1000000000UL) {
+ diff_secs += 1;
+ diff_nsecs -= 1000000000UL;
+ }
+ ts.tv_sec += diff_secs;
+ ts.tv_nsec += diff_nsecs;
+ return ts;
+}
+
#if 0
#include <stdio.h>
+#include "threads.h"
+
+#define TEST_SLEEP 1
int main(void) {
- int c = 200;
+ int c = 2000000;
int64_t j, r, t = 0;
+ pthread_mutex_t mtx;
+ pthread_mutex_init(&mtx, NULL);
+ pthread_cond_t cnd;
+ pthread_cond_init(&cnd, NULL);
mp_time_init();
for (int i = 0; i < c; i++) {
const int delay = rand() / (RAND_MAX / 1e5);
r = mp_time_us();
+#if TEST_SLEEP
mp_sleep_us(delay);
+#else
+ mpthread_cond_timedwait(&cnd, &mtx, r + delay);
+#endif
j = (mp_time_us() - r) - delay;
- printf("sleep time: sleep=%8i err=%5i\n", delay, (int)j);
+ printf("sleep time: t=%"PRId64" sleep=%8i err=%5i\n", r, delay, (int)j);
t += j;
}
fprintf(stderr, "average error:\t%i\n", (int)(t / c));