Started writing the new timer_darwinunix.c file; implemented the monotonic time functions for now. On non-macOS, we now require clock_gettime() to be successful, as GLib also does (at least as far back as the version that ships with Ubuntu 14.04); we also gather the time at first call and use that as the basis for returning a single integer from timerMonotonicNow(), so timerTimeSub() is a simple subtraction now. The logic for this conversion is based on the logic of timevalsub() in macOS's sys/time.h, though this is really simple to understand.
This commit is contained in:
parent
e9fd8cc878
commit
6a25efce63
|
@ -1,43 +0,0 @@
|
|||
// 22 april 2019
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include "testing.h"
|
||||
#include "testingpriv.h"
|
||||
|
||||
struct testingTimer {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
};
|
||||
|
||||
testingTimer *testingNewTimer(void)
|
||||
{
|
||||
return testingprivNew(testingTimer);
|
||||
}
|
||||
|
||||
void testingFreeTimer(testingTimer *t)
|
||||
{
|
||||
testingprivFree(t);
|
||||
}
|
||||
|
||||
void testingTimerStart(testingTimer *t)
|
||||
{
|
||||
t->start = mach_absolute_time();
|
||||
}
|
||||
|
||||
void testingTimerEnd(testingTimer *t)
|
||||
{
|
||||
t->end = mach_absolute_time();
|
||||
}
|
||||
|
||||
int64_t testingTimerNsec(testingTimer *t)
|
||||
{
|
||||
mach_timebase_info_data_t mt;
|
||||
uint64_t c;
|
||||
|
||||
mach_timebase_info(&mt);
|
||||
c = t->end - t->start;
|
||||
c = c * mt.numer / mt.denom;
|
||||
return (int64_t) c;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
// 23 april 2019
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "testing.h"
|
||||
#include "testingpriv.h"
|
||||
|
||||
struct testingTimer {
|
||||
struct timespec start;
|
||||
struct timespec end;
|
||||
};
|
||||
|
||||
testingTimer *testingNewTimer(void)
|
||||
{
|
||||
return testingprivNew(testingTimer);
|
||||
}
|
||||
|
||||
void testingFreeTimer(testingTimer *t)
|
||||
{
|
||||
testingprivFree(t);
|
||||
}
|
||||
|
||||
void testingTimerStart(testingTimer *t)
|
||||
{
|
||||
// TODO check errors
|
||||
clock_gettime(CLOCK_MONOTONIC, &(t->start));
|
||||
}
|
||||
|
||||
void testingTimerEnd(testingTimer *t)
|
||||
{
|
||||
// TODO check errors
|
||||
clock_gettime(CLOCK_MONOTONIC, &(t->end));
|
||||
}
|
||||
|
||||
// TODO replace with proper subtraction code
|
||||
int64_t testingTimerNsec(testingTimer *t)
|
||||
{
|
||||
int64_t nstart, nend;
|
||||
|
||||
nstart = ((int64_t) (t->start.tv_sec)) * testingNsecPerSec;
|
||||
nstart += t->start.tv_nsec;
|
||||
nend = ((int64_t) (t->end.tv_sec)) * testingNsecPerSec;
|
||||
nend += t->end.tv_nsec;
|
||||
return nend - nstart;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// 3 may 2019
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
timerTime timerMonotonicNow(void)
|
||||
{
|
||||
return (timerTime) mach_absolute_time();
|
||||
}
|
||||
|
||||
timerDuration timerTimeSub(timerTime end, timerTime start)
|
||||
{
|
||||
mach_timebase_info_data_t mt;
|
||||
timerTime c;
|
||||
timerDuration ret;
|
||||
|
||||
mach_timebase_info(&mt);
|
||||
c = end - start;
|
||||
ret = ((timerDuration) c) * mt.numer / mt.denom;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void mustclock_gettime(clockid_t id, struct timespec *ts)
|
||||
{
|
||||
int err;
|
||||
|
||||
errno = 0;
|
||||
if (clock_gettime(id, ts) != 0) {
|
||||
err = errno;
|
||||
fprintf(stderr, "*** internal error in timerMonotonicNow(): clock_gettime() failed: %s (%d)\n", strerror(err), err);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static struct timespec base;
|
||||
static pthread_once_t baseOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void baseInit(void)
|
||||
{
|
||||
mustclock_gettime(CLOCK_MONOTONIC, &base);
|
||||
}
|
||||
|
||||
timerTime timerMonotonicNow(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
timerTIme ret;
|
||||
int err;
|
||||
|
||||
err = pthread_once(&baseOnce, baseInit);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "*** internal error in timerMonotonicNow(): pthread_once() failed: %s (%d)\n", strerror(err), err);
|
||||
abort();
|
||||
}
|
||||
mustclock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
ts.tv_sec -= base.tv_sec;
|
||||
ts.tv_nsec -= base.tv_nsec;
|
||||
if (ts.tv_nsec < 0) { // this is safe because POSIX requires this to be of type long
|
||||
ts.tv_sec--;
|
||||
ts.tv_nsec += (long) timerSecond;
|
||||
}
|
||||
ret = ((timerTime) (ts.tv_sec)) * timerSecond;
|
||||
ret += (timerTime) (ts.tv_nsec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
timerDuration timerTimeSub(timerTime end, timerTime start)
|
||||
{
|
||||
return end - start;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue