mirror of https://github.com/flysand7/ciabatta.git
72 lines
2.1 KiB
C
72 lines
2.1 KiB
C
|
|
#define TIME_TICKS_PER_SEC 1000
|
|
#define FILE_TICKS_PER_SEC 10000000
|
|
#define FILE_TICKS_UNTIL_UNIX_EPOCH 116444736000000000ULL
|
|
|
|
#define NANOS_PER_SEC 1000000000
|
|
#define NANOS_PER_FILE_TICK (NANOS_PER_SEC / FILE_TICKS_PER_SEC)
|
|
#define NANOS_PER_TIME_TICK (NANOS_PER_SEC / TIME_TICKS_PER_SEC)
|
|
|
|
|
|
// Store the time since we started running the process
|
|
static uint64_t timer_freq;
|
|
static uint64_t timer_start;
|
|
|
|
void _setup_timer(void) {
|
|
LARGE_INTEGER freq, start;
|
|
QueryPerformanceFrequency(&freq);
|
|
QueryPerformanceCounter(&start);
|
|
timer_start = start.QuadPart;
|
|
timer_freq = freq.QuadPart;
|
|
}
|
|
|
|
static ULONGLONG win32_get_unix_nanos() {
|
|
FILETIME ft;
|
|
GetSystemTimeAsFileTime(&ft);
|
|
ULARGE_INTEGER ft64 = {
|
|
.LowPart = ft.dwLowDateTime,
|
|
.HighPart = ft.dwHighDateTime,
|
|
};
|
|
ULONGLONG fticks = ft64.QuadPart;
|
|
ULONGLONG unix_fticks = fticks - FILE_TICKS_UNTIL_UNIX_EPOCH;
|
|
ULONGLONG unix_nanos = unix_fticks * NANOS_PER_FILE_TICK;
|
|
return unix_nanos;
|
|
}
|
|
|
|
clock_t clock(void) {
|
|
LARGE_INTEGER curr;
|
|
if (!QueryPerformanceCounter(&curr)) {
|
|
return -1;
|
|
}
|
|
if (curr.QuadPart < timer_start) {
|
|
return -1;
|
|
}
|
|
clock_t ticks = curr.QuadPart - timer_start;
|
|
// Basically millis / timer_freq * CLOCKS_PER_SEC but more precise
|
|
return ticks / timer_freq * CLOCKS_PER_SEC
|
|
+ ticks % timer_freq * CLOCKS_PER_SEC / timer_freq;
|
|
}
|
|
|
|
time_t time(time_t *timer) {
|
|
ULONGLONG unix_nanos = win32_get_unix_nanos();
|
|
time_t timer_ticks = unix_nanos / NANOS_PER_TIME_TICK;
|
|
if(timer != NULL) {
|
|
*timer = timer_ticks;
|
|
}
|
|
return timer_ticks;
|
|
}
|
|
|
|
double difftime(time_t time1, time_t time0) {
|
|
double resolution = (double)TIME_TICKS_PER_SEC;
|
|
if(time1 >= time0) return (double)(time1 - time0) / resolution;
|
|
else return -(double)(time0 - time1) / resolution;
|
|
}
|
|
|
|
int timespec_get(struct timespec *ts, int base) {
|
|
if (base != TIME_UTC) return 0;
|
|
ULONGLONG unix_nanos = win32_get_unix_nanos();
|
|
ts->tv_sec = unix_nanos / NANOS_PER_SEC;
|
|
ts->tv_nsec = unix_nanos;
|
|
return base;
|
|
}
|