148 lines
4.3 KiB
C++
148 lines
4.3 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: Time.hpp
|
|
Date: 2021-6-17
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
#include <time.h>
|
|
#endif
|
|
|
|
namespace Aurora::Time
|
|
{
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
|
|
static AuInt64 ConvertTimestamp(const FILETIME &ft)
|
|
{
|
|
ULARGE_INTEGER ull;
|
|
ull.LowPart = ft.dwLowDateTime;
|
|
ull.HighPart = ft.dwHighDateTime;
|
|
return (ull.QuadPart - 126'435'537'000'000'000ull) / 10'000ULL;
|
|
}
|
|
|
|
static AuInt64 ConvertTimestampNs(const FILETIME &ft)
|
|
{
|
|
ULARGE_INTEGER ull;
|
|
ull.LowPart = ft.dwLowDateTime;
|
|
ull.HighPart = ft.dwHighDateTime;
|
|
return (ull.QuadPart - 126'435'537'000'000'000ull) * 100ULL;
|
|
}
|
|
|
|
static AuInt64 ConvertTimestamp(AuUInt64 timeIn)
|
|
{
|
|
return (126'435'537'000'000'000ull) + (AuUInt64(timeIn) * 10000ULL);
|
|
}
|
|
|
|
static AuInt64 ConvertTimestampNs(AuUInt64 timeIn)
|
|
{
|
|
return (126'435'537'000'000'000ull) + (AuUInt64(timeIn) / 100ULL);
|
|
}
|
|
|
|
#elif defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
#if defined(AURORA_IS_XNU_DERIVED)
|
|
static dispatch_time_t DispatchTimeFromAuSteadyAbsNS(AuUInt64 uSteadyTimeABSNS)
|
|
{
|
|
AuUInt64 uRet {};
|
|
uRet = uSteadyTimeABSNS / (1000000000ull / SteadyClockFrequency());
|
|
uRet &= ~((1ull << 63ull) | (1ull << 62ull));
|
|
uRet |= (1ull << 63ull);
|
|
return (dispatch_time_t)uRet;
|
|
}
|
|
#endif
|
|
|
|
static AuInt64 ConvertUnixTimespecToMs(const struct timespec &spec)
|
|
{
|
|
return ConvertUnixToAuroraMS(spec.tv_sec * 1000ULL + spec.tv_nsec / 1000000ULL);
|
|
}
|
|
|
|
static void ms2ts(struct timespec *ts, AuUInt64 ms)
|
|
{
|
|
ts->tv_sec = ms / 1000;
|
|
ts->tv_nsec = (ms % 1000) * 1000000;
|
|
}
|
|
|
|
static void ns2ts(struct timespec *ts, AuUInt64 ns)
|
|
{
|
|
ts->tv_sec = ns / 1'000'000'000ull;
|
|
ts->tv_nsec = ns % 1'000'000'000ull;
|
|
}
|
|
|
|
static void ms2tsabs(struct timespec *ts, unsigned long ms)
|
|
{
|
|
::clock_gettime(CLOCK_MONOTONIC, ts);
|
|
|
|
auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec;
|
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
|
|
|
ts->tv_sec += baseNS / 1'000'000'000ull;
|
|
ts->tv_nsec = remainderNS;
|
|
}
|
|
|
|
static void ms2tsabsRealtime(struct timespec *ts, unsigned long ms)
|
|
{
|
|
::clock_gettime(CLOCK_REALTIME, ts);
|
|
|
|
auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec;
|
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
|
|
|
ts->tv_sec += baseNS / 1'000'000'000ull;
|
|
ts->tv_nsec = remainderNS;
|
|
}
|
|
|
|
static void monoabsns2ts(struct timespec *ts, unsigned long long ns)
|
|
{
|
|
auto remainderNS = (AuUInt64)ns % (AuUInt64)1'000'000'000;
|
|
ts->tv_sec = ns / 1'000'000'000ull;
|
|
ts->tv_nsec = remainderNS;
|
|
}
|
|
|
|
static void auabsns2ts(struct timespec *ts, unsigned long long ns)
|
|
{
|
|
auto baseNS = ns + AuMSToNS<AuUInt64>(999'080'100'000);
|
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
|
|
|
ts->tv_sec = baseNS / 1'000'000'000ull;
|
|
ts->tv_nsec = remainderNS;
|
|
}
|
|
|
|
static void auabsms2ts(struct timespec *ts, unsigned long ms)
|
|
{
|
|
auabsns2ts(ts, AuMSToNS<AuUInt64>(ms));
|
|
}
|
|
|
|
static void ms2tvabs(struct timeval *tv, unsigned long ms)
|
|
{
|
|
timespec ts;
|
|
::clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
|
auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts.tv_nsec;
|
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
|
|
|
tv->tv_sec = ts.tv_sec;
|
|
tv->tv_sec += baseNS / 1'000'000'000ull;
|
|
tv->tv_usec = remainderNS / 1'000ull;
|
|
}
|
|
|
|
static void ms2tv(struct timeval *tv, unsigned long ms)
|
|
{
|
|
tv->tv_sec = ms / 1'000ull;
|
|
tv->tv_usec = (ms % 1'000ull) * 1'000ull;
|
|
}
|
|
|
|
static void ms2tsabsmono(struct timespec *ts, unsigned long ms)
|
|
{
|
|
clock_gettime(CLOCK_MONOTONIC, ts);
|
|
|
|
auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec;
|
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
|
|
|
ts->tv_sec += baseNS / 1'000'000'000ull;
|
|
ts->tv_nsec = remainderNS;
|
|
}
|
|
|
|
#endif
|
|
} |