jbus/lib/Common.cpp

81 lines
1.9 KiB
C++
Raw Normal View History

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