2017-01-07 03:13:23 +00:00
|
|
|
#ifndef _WIN32
|
|
|
|
#include <unistd.h>
|
2017-01-08 00:20:46 +00:00
|
|
|
#include <sys/time.h>
|
2017-01-07 03:13:23 +00:00
|
|
|
#if __APPLE__
|
|
|
|
#include <mach/mach_time.h>
|
2019-04-07 05:00:24 +00:00
|
|
|
#elif __linux__ || __FreeBSD__
|
|
|
|
#include <time.h>
|
2017-01-07 03:13:23 +00:00
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#endif
|
|
|
|
#include <windows.h>
|
2017-01-07 08:24:16 +00:00
|
|
|
#include <WinSock2.h>
|
2017-01-07 03:13:23 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "jbus/Common.hpp"
|
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
namespace jbus {
|
2017-01-07 03:13:23 +00:00
|
|
|
|
|
|
|
#if __APPLE__
|
|
|
|
static u64 MachToDolphinNum;
|
|
|
|
static u64 MachToDolphinDenom;
|
2017-01-07 08:24:16 +00:00
|
|
|
#elif _WIN32
|
|
|
|
static LARGE_INTEGER PerfFrequency;
|
2017-01-07 03:13:23 +00:00
|
|
|
#endif
|
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
u64 GetGCTicks() {
|
2017-01-07 03:13:23 +00:00
|
|
|
#if __APPLE__
|
2018-12-08 05:20:55 +00:00
|
|
|
return mach_absolute_time() * MachToDolphinNum / MachToDolphinDenom;
|
2017-01-08 00:20:46 +00:00
|
|
|
#elif __linux__ || __FreeBSD__
|
2018-12-08 05:20:55 +00:00
|
|
|
struct timespec tp;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &tp);
|
2017-01-07 03:13:23 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
return u64((tp.tv_sec * 1000000000ull) + tp.tv_nsec) * GetGCTicksPerSec() / 1000000000ull;
|
2017-01-07 08:24:16 +00:00
|
|
|
#elif _WIN32
|
2018-12-08 05:20:55 +00:00
|
|
|
LARGE_INTEGER perf;
|
|
|
|
QueryPerformanceCounter(&perf);
|
|
|
|
perf.QuadPart *= GetGCTicksPerSec();
|
|
|
|
perf.QuadPart /= PerfFrequency.QuadPart;
|
|
|
|
return perf.QuadPart;
|
2017-01-07 03:13:23 +00:00
|
|
|
#else
|
2018-12-08 05:20:55 +00:00
|
|
|
return 0;
|
2017-01-07 03:13:23 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
void WaitGCTicks(u64 ticks) {
|
2017-01-07 08:24:16 +00:00
|
|
|
#ifndef _WIN32
|
2018-12-08 05:20:55 +00:00
|
|
|
struct timeval tv = {};
|
|
|
|
tv.tv_sec = ticks / GetGCTicksPerSec();
|
|
|
|
tv.tv_usec = (ticks % GetGCTicksPerSec()) * 1000000 / GetGCTicksPerSec();
|
|
|
|
select(0, NULL, NULL, NULL, &tv);
|
2017-01-07 08:24:16 +00:00
|
|
|
#else
|
2018-12-08 05:20:55 +00:00
|
|
|
if (ticks < GetGCTicksPerSec() / 60) {
|
|
|
|
/* NT is useless for scheduling sub-millisecond intervals */
|
|
|
|
u64 start = GetGCTicks();
|
|
|
|
do {
|
|
|
|
Sleep(0);
|
|
|
|
} while (GetGCTicks() - start < ticks);
|
|
|
|
} else {
|
|
|
|
/* Use normal Sleep() for durations longer than ~16ms */
|
|
|
|
Sleep(ticks * 1000 / GetGCTicksPerSec() + (ticks % GetGCTicksPerSec()) * 1000 / GetGCTicksPerSec());
|
|
|
|
}
|
2017-01-07 08:24:16 +00:00
|
|
|
#endif
|
2017-01-07 03:13:23 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
void Initialize() {
|
2017-01-07 03:13:23 +00:00
|
|
|
#if __APPLE__
|
2018-12-08 05:20:55 +00:00
|
|
|
mach_timebase_info_data_t timebase;
|
|
|
|
mach_timebase_info(&timebase);
|
|
|
|
MachToDolphinNum = GetGCTicksPerSec() * timebase.numer;
|
|
|
|
MachToDolphinDenom = 1000000000ull * timebase.denom;
|
2017-01-07 08:24:16 +00:00
|
|
|
#elif _WIN32
|
2018-12-08 05:20:55 +00:00
|
|
|
WSADATA initData;
|
|
|
|
WSAStartup(MAKEWORD(2, 2), &initData);
|
|
|
|
QueryPerformanceFrequency(&PerfFrequency);
|
2017-01-07 03:13:23 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
} // namespace jbus
|