timesynk/engine/timer.c

92 lines
2.3 KiB
C

#include "timer.h"
#if __MACH__
#include <CoreServices/CoreServices.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#endif
#include <stdio.h>
#if _WIN32 | _WIN64
#include <windows.h>
#endif
int64_t setPTime(struct PTime *time, int64_t seconds, int64_t milliseconds, int64_t nanoseconds) {
time->n = nanoseconds + (milliseconds*1000000) + (seconds*1000000000);
time->m = time->n / 1000000;
time->s = time->n / 1000000000;
return time->n;
}
inline int64_t getPTime(struct PTime *time) {
#if _WIN32 | _WIN64
int64_t ticks = GetTickCount();
time->s = ticks/1000;
time->m = ticks;
time->n = ticks*1000000;
#elif __MACH__
mach_timebase_info_data_t info;
mach_timebase_info(&info);
uint64_t m_time = mach_absolute_time();
m_time *= info.numer;
m_time /= info.denom;
time->n = m_time;
time->m = m_time / 1000000;
time->s = time->m / 1000;
/*#elif __i586__
struct { int32 low, high; } counter;
__asm push EAX
__asm push EDX
__asm __emit 0fh __asm __emit 031h // RDTSC
__asm mov counter.low, EAX
__asm mov counter.high, EDX
__asm pop EDX
__asm pop EAX
*/
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
time->s = ts.tv_sec;
time->n = (ts.tv_sec * 1000000000) + ts.tv_nsec;
time->m = time->n / 1000000;
#endif
return time->n;
}
inline int64_t getPTimeDiff(struct PTime *time_delta, struct PTime *time_a, struct PTime *time_b) {
if (time_a == NULL || time_b == NULL) return 0;
if (time_delta != NULL) {
int64_t s_diff = time_a->s - time_b->s;
int64_t m_diff = time_a->m - time_b->m;
int64_t n_diff = time_a->n - time_b->n;
time_delta->s = s_diff;
time_delta->m = m_diff;
time_delta->n = n_diff;
return n_diff;
} else {
return time_a->n - time_b->n;
}
}
inline void doNanoSleep(int64_t nanoseconds) {
#if _WIN32 | _WIN64
Sleep(nanoseconds/1000000);
#else
struct timespec ts;
double ns_fraction = nanoseconds / 1000000000;
ts.tv_sec = ns_fraction;
if (ns_fraction >= 1.0f)
ts.tv_nsec = nanoseconds - ns_fraction;
else
ts.tv_nsec = nanoseconds;
if (ts.tv_nsec < 0) ts.tv_nsec = 0;
//printf("snoozing for %lds and %ldns\n", ts.tv_sec, ts.tv_nsec);
nanosleep(&ts, NULL);
//if (nanosleep(&ts, NULL) < 0)
//printf("ERR: had trouble sleeping\n"); // FIXME: THIS ERRORS ALOT
#endif
}