Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
add in OS X Monotonic clock as well as handling fall-back incase the …
Browse files Browse the repository at this point in the history
…OSX/Linux system doesn't have a monotonic clock.

Code curtesy of Thomas Habets ( https://github.com/ThomasHabets/monotonic_clock )
  • Loading branch information
urkle committed May 3, 2013
1 parent 9d83ba5 commit 0f1a58f
Showing 1 changed file with 74 additions and 46 deletions.
120 changes: 74 additions & 46 deletions src/timer/unix/SDL_systimer.c
Expand Up @@ -34,85 +34,113 @@
for __USE_POSIX199309
Tommi Kyntola (tommi.kyntola@ray.fi) 27/09/2005
*/
/* Reworked monotonic clock to not assume the current system has one
as not all linux kernels provide a monotonic clock (yeah recent ones
probably do)
Also added OS X Monotonic clock support
Based on work in https://github.com/ThomasHabets/monotonic_clock
*/
#if HAVE_NANOSLEEP || HAVE_CLOCK_GETTIME
#include <time.h>
#endif
#ifdef __APPLE__
#include <mach/mach_time.h>
#endif

/* The first ticks value of the application */
#ifdef HAVE_CLOCK_GETTIME
static struct timespec start;
#else
static struct timeval start;
#endif /* HAVE_CLOCK_GETTIME */

#if HAVE_CLOCK_GETTIME
static struct timespec start_ts;
#elif defined(__APPLE__)
static uint64_t start_mach;
mach_timebase_info_data_t mach_base_info;
#endif
static SDL_bool has_monotonic_time = SDL_FALSE;
static struct timeval start_tv;

void
SDL_StartTicks(void)
{
/* Set first ticks value */
#if HAVE_CLOCK_GETTIME
clock_gettime(CLOCK_MONOTONIC, &start);
#else
gettimeofday(&start, NULL);
if (clock_gettime(CLOCK_MONOTONIC, &start_ts) == 0) {
has_monotonic_time = SDL_TRUE;
} else
#elif defined(__APPLE__)
start_mach = mach_absolute_time();
kern_return_t ret = mach_timebase_info(&mach_base_info);
if (ret == 0) {
has_monotonic_time = SDL_TRUE;
} else
#endif
{
gettimeofday(&start_tv, NULL);
}
}

Uint32
SDL_GetTicks(void)
{
#if HAVE_CLOCK_GETTIME
Uint32 ticks;
struct timespec now;

clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
start.tv_nsec) / 1000000;
return (ticks);
#else
Uint32 ticks;
struct timeval now;

gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
start.tv_usec) / 1000;
return (ticks);
if (has_monotonic_time) {
#if HAVE_CLOCK_GETTIME
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start_ts.tv_sec) * 1000 + (now.tv_nsec -
start_ts.tv_nsec) / 1000000;
#elif defined(__APPLE__)
uint64_t now = mach_absolute_time();
ticks = (now - start_mach) * mach_base_info.numer / mach_base_info.denom / 1000000;
#endif
} else {
struct timeval now;

gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start_tv.tv_sec) * 1000 + (now.tv_usec -
start_tv.tv_usec) / 1000;
}
return (ticks);
}

Uint64
SDL_GetPerformanceCounter(void)
{
#if HAVE_CLOCK_GETTIME
Uint64 ticks;
struct timespec now;

clock_gettime(CLOCK_MONOTONIC, &now);
ticks = now.tv_sec;
ticks *= 1000000000;
ticks += now.tv_nsec;
return (ticks);
#else
Uint64 ticks;
struct timeval now;

gettimeofday(&now, NULL);
ticks = now.tv_sec;
ticks *= 1000000;
ticks += now.tv_usec;
return (ticks);
if (has_monotonic_time) {
#if HAVE_CLOCK_GETTIME
struct timespec now;

clock_gettime(CLOCK_MONOTONIC, &now);
ticks = now.tv_sec;
ticks *= 1000000000;
ticks += now.tv_nsec;
#elif defined(__APPLE__)
ticks = mach_absolute_time();
#endif
} else {
struct timeval now;

gettimeofday(&now, NULL);
ticks = now.tv_sec;
ticks *= 1000000;
ticks += now.tv_usec;
}
return (ticks);
}

Uint64
SDL_GetPerformanceFrequency(void)
{
if (has_monotonic_time) {
#if HAVE_CLOCK_GETTIME
return 1000000000;
#else
return 1000000;
return 1000000000;
#elif defined(__APPLE__)
return mach_base_info.denom / mach_base_info.numer * 1000000;
#endif
} else {
return 1000000;
}
}

void
Expand Down

0 comments on commit 0f1a58f

Please sign in to comment.