Fix build on OS X that might not have clock_gettime().

Older versions of OS X don't implement clock_gettime() and no(?) version
seems to implement CLOCK_MONOTONIC. Work around this by implementing an
OS X specific variant of Sys_Microseconds() that relies on Mach APIs
provided by all OS X versions...

While at it alter the generic variant so that CLOCK_MONOTONIC is used
only if it's available. CLOCK_REALTIME as a fallback should be good
enough in most cases.

This is believed to fix issue #239.
This commit is contained in:
Yamagi Burmeister 2017-10-02 17:58:03 +02:00 committed by Daniel Gibson
parent 4bfd1cb9d4
commit 3d459be4c1

View file

@ -46,6 +46,11 @@
#include <dirent.h>
#include <time.h>
#ifdef __APPLE__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#include "../../common/header/common.h"
#include "../../common/header/glob.h"
#include "../generic/header/input.h"
@ -79,22 +84,54 @@ Sys_Init(void)
{
}
#ifdef __APPLE__
long long
Sys_Microseconds(void)
{
static struct timespec last;
struct timespec now;
clock_serv_t cclock;
mach_timespec_t now;
static mach_timespec_t first;
clock_gettime(CLOCK_MONOTONIC, &now);
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
clock_get_time(cclock, &now);
if(last.tv_sec == 0)
{
clock_gettime(CLOCK_MONOTONIC, &last);
return last.tv_nsec / 1000ll;
if (first == 0) {
clock_get_time(cclock, &first);
mach_port_deallocate(mach_task_self(), cclock);
return (first / 1000ll) - 1001ll;
}
long long sec = now.tv_sec - last.tv_sec;
long long nsec = now.tv_nsec - last.tv_nsec;
mach_port_deallocate(mach_task_self(), cclock);
return (now - first) / 1000ll;
}
#else // !__APPLE__
long long
Sys_Microseconds(void)
{
static struct timespec first;
struct timespec now;
#ifdef _POSIX_MONOTONIC_CLOCK
clock_gettime(CLOCK_MONOTONIC, &now);
#else
clock_gettime(CLOCK_REALTIME, &now);
#endif
if(first.tv_sec == 0)
{
#ifdef _POSIX_MONOTONIC_CLOCK
clock_gettime(CLOCK_MONOTONIC, &first);
#else
clock_gettime(CLOCK_REALTIME, &first);
#endif
return (first.tv_nsec / 1000ll) - 1001ll;
}
long long sec = now.tv_sec - first.tv_sec;
long long nsec = now.tv_nsec - first.tv_nsec;
if(nsec < 0)
{
@ -104,6 +141,7 @@ Sys_Microseconds(void)
return sec*1000000ll + nsec/1000ll;
}
#endif // __APPLE__
int
Sys_Milliseconds(void)