[*] Begin enforcing steady time
[+] IOProcessor::WakeupThread [+] NT: Begin hacking in timeBeginPeriod (must spam it in some places) [+] ConsoleTTY (more specifically the win32 calls) are too slow to run on the mainthread. Delegate to worker. [*] AuTime.CurrentClockSteady [*] AuTime.CurrentClockSteadyMS [*] AuTime.CurrentClockSteadyNS
This commit is contained in:
parent
bb9c383aee
commit
72dc0d715e
@ -61,7 +61,8 @@
|
|||||||
"ws2_32.lib",
|
"ws2_32.lib",
|
||||||
"Ntdll.lib",
|
"Ntdll.lib",
|
||||||
"Wer.lib",
|
"Wer.lib",
|
||||||
"wintrust.lib"
|
"wintrust.lib",
|
||||||
|
"Winmm.lib"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -41,6 +41,8 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
virtual bool SubmitIOWorkItem (const AuSPtr<IIOProcessorWorkUnit> &work) = 0;
|
virtual bool SubmitIOWorkItem (const AuSPtr<IIOProcessorWorkUnit> &work) = 0;
|
||||||
|
|
||||||
|
virtual void WakeupThread () = 0;
|
||||||
|
|
||||||
// Inter-frame callbacks indicating point of execution throughout the [START](optional [yield])[IO][IO TICK][WORK ITEMS][EPILOGUE][END OF FRAME] frame
|
// Inter-frame callbacks indicating point of execution throughout the [START](optional [yield])[IO][IO TICK][WORK ITEMS][EPILOGUE][END OF FRAME] frame
|
||||||
virtual bool AddEventListener (const AuSPtr<IIOProcessorEventListener> &eventListener) = 0;
|
virtual bool AddEventListener (const AuSPtr<IIOProcessorEventListener> &eventListener) = 0;
|
||||||
virtual void RemoveEventListener (const AuSPtr<IIOProcessorEventListener> &eventListener) = 0;
|
virtual void RemoveEventListener (const AuSPtr<IIOProcessorEventListener> &eventListener) = 0;
|
||||||
|
@ -44,6 +44,12 @@ namespace Aurora::Time
|
|||||||
*/
|
*/
|
||||||
AUKN_SYM AuUInt64 CurrentClockNS();
|
AUKN_SYM AuUInt64 CurrentClockNS();
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 CurrentClockSteady();
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 CurrentClockSteadyMS();
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 CurrentClockSteadyNS();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Translates the Aurora epoch to the standard unix epoch
|
Translates the Aurora epoch to the standard unix epoch
|
||||||
*/
|
*/
|
||||||
|
@ -317,7 +317,7 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
success |= PollInternal(block);
|
success |= PollInternal(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -445,7 +445,7 @@ namespace Aurora::Async
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (state->pendingWorkItems.empty());
|
} while (state->pendingWorkItems.empty() && block);
|
||||||
|
|
||||||
if (group->workQueue.empty())
|
if (group->workQueue.empty())
|
||||||
{
|
{
|
||||||
@ -537,6 +537,7 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
tlsCallStack++;
|
tlsCallStack++;
|
||||||
|
|
||||||
|
//SysBenchmark(fmt::format("RunAsync: {}", block));
|
||||||
// Dispatch
|
// Dispatch
|
||||||
oops->RunAsync();
|
oops->RunAsync();
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "SWInfo/AuSWInfo.hpp"
|
#include "SWInfo/AuSWInfo.hpp"
|
||||||
#if defined(AURORA_PLATFORM_WIN32)
|
#if defined(AURORA_PLATFORM_WIN32)
|
||||||
#include "Extensions/Win32/DarkTheme.hpp"
|
#include "Extensions/Win32/DarkTheme.hpp"
|
||||||
|
#include <timeapi.h>
|
||||||
#endif
|
#endif
|
||||||
#include "Process/Process.hpp"
|
#include "Process/Process.hpp"
|
||||||
#include "Exit/AuExit.hpp"
|
#include "Exit/AuExit.hpp"
|
||||||
@ -49,6 +50,8 @@ static void Init()
|
|||||||
gRuntimeRunLevel = 1;
|
gRuntimeRunLevel = 1;
|
||||||
tlsHackIsMainThread = true;
|
tlsHackIsMainThread = true;
|
||||||
#if defined(AURORA_PLATFORM_WIN32)
|
#if defined(AURORA_PLATFORM_WIN32)
|
||||||
|
::timeBeginPeriod(1);
|
||||||
|
|
||||||
Aurora::Extensions::Win32::InitDarkMode();
|
Aurora::Extensions::Win32::InitDarkMode();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -85,6 +88,10 @@ static void Pump()
|
|||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
::LinuxSuperSecretIOTick();
|
::LinuxSuperSecretIOTick();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_PLATFORM_WIN32)
|
||||||
|
::timeBeginPeriod(1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RuntimeLateClean();
|
static void RuntimeLateClean();
|
||||||
|
@ -97,15 +97,26 @@ namespace Aurora::Console
|
|||||||
Logging::InitLoggers();
|
Logging::InitLoggers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pump()
|
void PumpOnMain()
|
||||||
{
|
{
|
||||||
Commands::PumpCommands();
|
Commands::PumpCommands();
|
||||||
ConsoleStd::Pump();
|
ConsoleStd::Pump();
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumb
|
||||||
|
void PumpOffMain()
|
||||||
|
{
|
||||||
ConsoleWxWidgets::Pump();
|
ConsoleWxWidgets::Pump();
|
||||||
ConsoleFIO::Pump();
|
ConsoleFIO::Pump();
|
||||||
ConsoleTTY::Pump();
|
ConsoleTTY::Pump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pump()
|
||||||
|
{
|
||||||
|
PumpOnMain();
|
||||||
|
PumpOffMain();
|
||||||
|
}
|
||||||
|
|
||||||
void Exit()
|
void Exit()
|
||||||
{
|
{
|
||||||
gDefaultSinks.clear();
|
gDefaultSinks.clear();
|
||||||
|
@ -17,4 +17,7 @@ namespace Aurora::Console
|
|||||||
void Init2();
|
void Init2();
|
||||||
void Pump();
|
void Pump();
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
|
void PumpOffMain();
|
||||||
|
void PumpOnMain();
|
||||||
}
|
}
|
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
namespace Aurora::Console::ConsoleTTY
|
namespace Aurora::Console::ConsoleTTY
|
||||||
{
|
{
|
||||||
|
static AuThreads::ThreadUnique_t gConsoleTTYThread;
|
||||||
|
static bool gMultiThreadTTY { true };
|
||||||
|
static bool gBuggyFastAppend { false };
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
@ -715,6 +718,7 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
|
|
||||||
void TTYConsole::Pump()
|
void TTYConsole::Pump()
|
||||||
{
|
{
|
||||||
|
//SysBenchmark("Console TTY pump");
|
||||||
if (!gTTYConsoleEnabled)
|
if (!gTTYConsoleEnabled)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -722,13 +726,20 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
|
|
||||||
if (NoncanonicalMode())
|
if (NoncanonicalMode())
|
||||||
{
|
{
|
||||||
|
//SysBenchmark("NoncanonicalTick");
|
||||||
NoncanonicalTick();
|
NoncanonicalTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//SysBenchmark("flush (redraw)");
|
||||||
Flush();
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//SysBenchmark("history");
|
||||||
PumpHistory();
|
PumpHistory();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTYConsole::OnEnter()
|
void TTYConsole::OnEnter()
|
||||||
{
|
{
|
||||||
@ -862,6 +873,10 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
if (iScrollPos == -1)
|
if (iScrollPos == -1)
|
||||||
{
|
{
|
||||||
if (this->screenBuffer.size() > maxLines)
|
if (this->screenBuffer.size() > maxLines)
|
||||||
|
{
|
||||||
|
// TODO (Reece): Removing optimization bc it was broken. This is a nightmare.
|
||||||
|
|
||||||
|
if (!gBuggyFastAppend)
|
||||||
{
|
{
|
||||||
static bool bSingleShot {};
|
static bool bSingleShot {};
|
||||||
if (!AuExchange(bSingleShot, true))
|
if (!AuExchange(bSingleShot, true))
|
||||||
@ -869,7 +884,6 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
EnterScrollMode();
|
EnterScrollMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO (Reece): Removing optimization bc it was broken. This is a nightmare.
|
|
||||||
auto indexBeforePadding = (this->GetBannerFootBorder() ? 1 + this->topLogPadding : 0) + this->topLogPaddingExtra;
|
auto indexBeforePadding = (this->GetBannerFootBorder() ? 1 + this->topLogPadding : 0) + this->topLogPaddingExtra;
|
||||||
auto startIndex = this->GetTopBorder() + this->GetBannerLines() + indexBeforePadding;
|
auto startIndex = this->GetTopBorder() + this->GetBannerLines() + indexBeforePadding;
|
||||||
|
|
||||||
@ -883,6 +897,26 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// this is still buggy as shit but we NEEEEED it
|
||||||
|
// youll notice whitespace appear as soon as we start overflowing but eh
|
||||||
|
for (int i = startIndex + maxLines; i < this->currentHeight; i++)
|
||||||
|
{
|
||||||
|
this->BlankLine(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TTYScrollBuffer(delta);
|
||||||
|
|
||||||
|
for (int i = indexBeforePadding; i < startIndex; i++)
|
||||||
|
{
|
||||||
|
this->BlankLine(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
forceRedrawIfFalse = true;
|
||||||
|
drawPos = startIndex + maxLines - delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
drawPos = startIndex + oldSize;
|
drawPos = startIndex + oldSize;
|
||||||
}
|
}
|
||||||
@ -1044,12 +1078,14 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
// Account for race conditions of size-change during draw
|
// Account for race conditions of size-change during draw
|
||||||
if (PermitDoubleBuffering())
|
if (PermitDoubleBuffering())
|
||||||
{
|
{
|
||||||
bTryAgain = !EndBuffering();
|
bTryAgain = !EndBuffering();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->bTriggerRedraw = false;
|
this->bTriggerRedraw = false;
|
||||||
}
|
}
|
||||||
@ -1981,9 +2017,37 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
return this->topLogPaddingExtra;
|
return this->topLogPaddingExtra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MainTTY()
|
||||||
|
{
|
||||||
|
while (AuIsThreadRunning())
|
||||||
|
{
|
||||||
|
AuThreading::Sleep(1000 / 20);
|
||||||
|
gTTYConsole.Pump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
gTTYConsole.Init();
|
gTTYConsole.Init();
|
||||||
|
|
||||||
|
if (gMultiThreadTTY)
|
||||||
|
{
|
||||||
|
gConsoleTTYThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
||||||
|
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(MainTTY)),
|
||||||
|
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
|
||||||
|
"ConsoleTTY pumper (win32 is slow as shit ok?)"
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!gConsoleTTYThread)
|
||||||
|
{
|
||||||
|
gMultiThreadTTY = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gConsoleTTYThread->SetThrottle(AuThreads::EThreadThrottle::eEfficient);
|
||||||
|
gConsoleTTYThread->SetPriority(AuThreads::EThreadPriority::ePrioHigh);
|
||||||
|
gConsoleTTYThread->Run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Exit()
|
void Exit()
|
||||||
@ -1997,9 +2061,13 @@ namespace Aurora::Console::ConsoleTTY
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Pump()
|
void Pump()
|
||||||
|
{
|
||||||
|
// :(
|
||||||
|
if (!gMultiThreadTTY)
|
||||||
{
|
{
|
||||||
gTTYConsole.Pump();
|
gTTYConsole.Pump();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AUKN_SYM AuSPtr<ITTYConsole> GetTTYConsole()
|
AUKN_SYM AuSPtr<ITTYConsole> GetTTYConsole()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <Source/Console/ConsoleFIO/ConsoleFIO.hpp>
|
#include <Source/Console/ConsoleFIO/ConsoleFIO.hpp>
|
||||||
#include <Source/RuntimeInternal.hpp>
|
#include <Source/RuntimeInternal.hpp>
|
||||||
#include <Source/Console/Flusher.hpp>
|
#include <Source/Console/Flusher.hpp>
|
||||||
|
#include <Source/Console/Console.hpp>
|
||||||
|
|
||||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||||
void LinuxSuperSecretIOTick();
|
void LinuxSuperSecretIOTick();
|
||||||
@ -118,7 +119,7 @@ namespace Aurora::Grug
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// he's a lazy bastard (ira type insult)
|
// he's a lazy bastard
|
||||||
gGrugsBigWorld->SetThrottle(AuThreads::EThreadThrottle::eEfficient);
|
gGrugsBigWorld->SetThrottle(AuThreads::EThreadThrottle::eEfficient);
|
||||||
gGrugsBigWorld->SetPriority(AuThreads::EThreadPriority::ePrioLow);
|
gGrugsBigWorld->SetPriority(AuThreads::EThreadPriority::ePrioLow);
|
||||||
gGrugsBigWorld->Run();
|
gGrugsBigWorld->Run();
|
||||||
@ -200,6 +201,7 @@ namespace Aurora::Grug
|
|||||||
void GrugFlushFlushs()
|
void GrugFlushFlushs()
|
||||||
{
|
{
|
||||||
Logging::ForceFlushFlush();
|
Logging::ForceFlushFlush();
|
||||||
Console::ForceFlush();
|
Aurora::Console::PumpOffMain();
|
||||||
|
//Console::ForceFlush();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -478,9 +478,12 @@ namespace Aurora::IO
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->items.mutex); // < critical section / reentrant | can nest submission
|
AU_LOCK_GUARD(this->items.mutex); // < critical section / reentrant | can nest submission
|
||||||
this->items.cvEvent->Set();
|
this->items.cvEvent->Set();
|
||||||
auto bRet = AuTryInsert(this->workUnits, work);
|
return AuTryInsert(this->workUnits, work);
|
||||||
//this->pLoopQueue->Commit(); // required to wake up async threads
|
}
|
||||||
return bRet;
|
|
||||||
|
void IOProcessor::WakeupThread()
|
||||||
|
{
|
||||||
|
this->items.cvEvent->Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOProcessor::AddEventListener(const AuSPtr<IIOProcessorEventListener> &eventListener)
|
bool IOProcessor::AddEventListener(const AuSPtr<IIOProcessorEventListener> &eventListener)
|
||||||
|
@ -81,6 +81,8 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
bool HasItems() override;
|
bool HasItems() override;
|
||||||
|
|
||||||
|
void WakeupThread();
|
||||||
|
|
||||||
bool CheckThread();
|
bool CheckThread();
|
||||||
|
|
||||||
bool RequestRemovalForItemFromAnyThread(const AuSPtr<IIOProcessorItem> &processor);
|
bool RequestRemovalForItemFromAnyThread(const AuSPtr<IIOProcessorItem> &processor);
|
||||||
|
@ -220,7 +220,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
if (ms)
|
if (ms)
|
||||||
{
|
{
|
||||||
src->timeoutAbs = (AuUInt64)ms + AuTime::CurrentClockMS();
|
src->timeoutAbs = (AuUInt64)ms + AuTime::CurrentClockSteadyMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AuTryInsert(this->sources_, src))
|
if (!AuTryInsert(this->sources_, src))
|
||||||
@ -426,7 +426,7 @@ namespace Aurora::IO::Loop
|
|||||||
AuUInt64 timeout {timeoutIn};
|
AuUInt64 timeout {timeoutIn};
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
timeout += AuTime::CurrentClockMS();
|
timeout += AuTime::CurrentClockSteadyMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -461,7 +461,7 @@ namespace Aurora::IO::Loop
|
|||||||
// but this hack should apply to wait any as well, so i'm moving it to the DoTick function
|
// but this hack should apply to wait any as well, so i'm moving it to the DoTick function
|
||||||
|
|
||||||
anythingLeft = epollReference.startingWorkRead.size() || epollReference.startingWorkWrite.size();
|
anythingLeft = epollReference.startingWorkRead.size() || epollReference.startingWorkWrite.size();
|
||||||
bTimeout = timeout ? AuTime::CurrentClockMS() >= timeout : false;
|
bTimeout = timeout ? AuTime::CurrentClockSteadyMS() >= timeout : false;
|
||||||
} while (anythingLeft && !bTimeout);
|
} while (anythingLeft && !bTimeout);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -478,7 +478,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
timeout += AuTime::CurrentClockMS();
|
timeout += AuTime::CurrentClockSteadyMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuUInt32 cTicked {};
|
AuUInt32 cTicked {};
|
||||||
@ -532,7 +532,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
timeout += AuTime::CurrentClockMS();
|
timeout += AuTime::CurrentClockSteadyMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bTryAgain {};
|
bool bTryAgain {};
|
||||||
@ -671,28 +671,10 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// syscall epoll_pwait2 is fucking broken and the dipshits who wrote the test used relative values
|
|
||||||
//
|
|
||||||
// Nothing I tried worked.
|
|
||||||
//
|
|
||||||
// Am I stupid? Probably, but...
|
|
||||||
// (1) no one as far as i can tell has ever written anything using this syscall, per a github search
|
|
||||||
// (2) i found one reference that the that are the linux kernel developers used MONO time for this
|
|
||||||
// one timespec API unlike everything else; using an abs value rel to that clock didn't change
|
|
||||||
// anything.
|
|
||||||
// (3) i found a test that would indicate its relative despite the fact UNIX/Linux sync APIs
|
|
||||||
// tend to use abs time
|
|
||||||
//
|
|
||||||
// What does my experience working on xenus tell me?
|
|
||||||
// Because the gOOOOglers in the form of linux kernel developers were faced with an issue that
|
|
||||||
// couldn't be solved by involve copy/pasting memory map code, making a mess of public headers,
|
|
||||||
// or taking credit for third party driver code as their own kernel code; they indeed are to
|
|
||||||
// blame for making my life miserable once again. Something about this aint adding up.
|
|
||||||
|
|
||||||
AuInt64 deltaMS = 0;
|
AuInt64 deltaMS = 0;
|
||||||
if (time)
|
if (time)
|
||||||
{
|
{
|
||||||
deltaMS = AuMin(AuInt64(4), (AuInt64)time - (AuInt64)AuTime::CurrentClockMS());
|
deltaMS = AuMin(AuInt64(4), (AuInt64)time - (AuInt64)AuTime::CurrentClockSteadyMS());
|
||||||
if (deltaMS < 0)
|
if (deltaMS < 0)
|
||||||
{
|
{
|
||||||
deltaMS = 0;
|
deltaMS = 0;
|
||||||
@ -771,7 +753,7 @@ namespace Aurora::IO::Loop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
now = AuTime::CurrentClockMS();
|
now = AuTime::CurrentClockSteadyMS();
|
||||||
|
|
||||||
if (!bTicked)
|
if (!bTicked)
|
||||||
{
|
{
|
||||||
@ -786,7 +768,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
if (!now)
|
if (!now)
|
||||||
{
|
{
|
||||||
now = AuTime::CurrentClockMS();
|
now = AuTime::CurrentClockSteadyMS();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto itr = this->sources_.begin(); itr != this->sources_.end(); )
|
for (auto itr = this->sources_.begin(); itr != this->sources_.end(); )
|
||||||
|
@ -43,7 +43,7 @@ namespace Aurora::IO::Loop
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time < timeoutAbs)
|
if (time < this->timeoutAbs)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ namespace Aurora::IO::Loop
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->sourceMutex_);
|
AU_LOCK_GUARD(this->sourceMutex_);
|
||||||
|
|
||||||
if (!AuTryInsert(this->addedSources_, AuMakeTuple(source, AuTime::CurrentInternalClockMS() + maxTimeout, SourceCallbacks {})))
|
if (!AuTryInsert(this->addedSources_, AuMakeTuple(source, AuTime::CurrentClockSteadyMS() + maxTimeout, SourceCallbacks {})))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -657,7 +657,7 @@ namespace Aurora::IO::Loop
|
|||||||
// Le great iterate
|
// Le great iterate
|
||||||
Iterator queueIterator(this);
|
Iterator queueIterator(this);
|
||||||
AuSInt indexOffset {};
|
AuSInt indexOffset {};
|
||||||
auto now = AuTime::CurrentInternalClockMS();
|
auto now = AuTime::CurrentClockSteadyMS();
|
||||||
for (queueIterator.Start(); queueIterator.End() != queueIterator.itr; )
|
for (queueIterator.Start(); queueIterator.End() != queueIterator.itr; )
|
||||||
{
|
{
|
||||||
auto &source = *queueIterator.itr;
|
auto &source = *queueIterator.itr;
|
||||||
|
@ -512,9 +512,12 @@ namespace Aurora::IO::UNIX
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuInt64 iStartTime {};
|
||||||
|
AuInt64 iTargetTime {};
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
AuTime::ms2tsabs(&targetTime, timeout);
|
iStartTime = AuTime::CurrentClockSteadyMS();
|
||||||
|
iTargetTime = iStartTime + timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LinuxOverlappedTrySubmitWork())
|
if (!LinuxOverlappedTrySubmitWork())
|
||||||
@ -526,6 +529,17 @@ namespace Aurora::IO::UNIX
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
auto delta = iTargetTime - AuTime::CurrentClockSteadyMS();
|
||||||
|
if (delta <= 0)
|
||||||
|
{
|
||||||
|
return dwApcsSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuTime::ns2ts(&targetTime, delta);
|
||||||
|
}
|
||||||
|
|
||||||
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
@ -600,9 +614,12 @@ namespace Aurora::IO::UNIX
|
|||||||
return epoll_wait(epfd, events, maxevents, timeout);
|
return epoll_wait(epfd, events, maxevents, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuInt64 iStartTime {};
|
||||||
|
AuInt64 iTargetTime {};
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
AuTime::ms2tsabs(&targetTime, timeout);
|
iStartTime = AuTime::CurrentClockSteadyMS();
|
||||||
|
iTargetTime = iStartTime + timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LinuxOverlappedTrySubmitWork())
|
if (!LinuxOverlappedTrySubmitWork())
|
||||||
@ -640,6 +657,17 @@ namespace Aurora::IO::UNIX
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
auto delta = iTargetTime - AuTime::CurrentClockSteadyMS();
|
||||||
|
if (delta <= 0)
|
||||||
|
{
|
||||||
|
return dwApcsSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuTime::ns2ts(&targetTime, delta);
|
||||||
|
}
|
||||||
|
|
||||||
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
@ -739,9 +767,12 @@ namespace Aurora::IO::UNIX
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuInt64 iStartTime {};
|
||||||
|
AuInt64 iTargetTime {};
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
AuTime::ms2tsabs(&targetTime, timeout);
|
iStartTime = AuTime::CurrentClockSteadyMS();
|
||||||
|
iTargetTime = iStartTime + timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LinuxOverlappedTrySubmitWork())
|
if (!LinuxOverlappedTrySubmitWork())
|
||||||
@ -794,6 +825,17 @@ namespace Aurora::IO::UNIX
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
auto delta = iTargetTime - AuTime::CurrentClockSteadyMS();
|
||||||
|
if (delta <= 0)
|
||||||
|
{
|
||||||
|
return dwApcsSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuTime::ns2ts(&targetTime, delta);
|
||||||
|
}
|
||||||
|
|
||||||
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
temp = io_getevents(io->context, 1, 512, ioEvents, timeout ? &targetTime : nullptr);
|
||||||
|
|
||||||
if (temp >= 0)
|
if (temp >= 0)
|
||||||
|
@ -15,23 +15,28 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex) : mutex_(std::dynamic_pointer_cast<IConditionMutexEx>(mutex))
|
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex) : mutex_(std::dynamic_pointer_cast<IConditionMutexEx>(mutex))
|
||||||
{
|
{
|
||||||
auto ret = pthread_cond_init(&pthreadCv_, NULL);
|
pthread_condattr_t attr;
|
||||||
|
|
||||||
|
::pthread_condattr_init(&attr);
|
||||||
|
::pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
||||||
|
|
||||||
|
auto ret = ::pthread_cond_init(&this->pthreadCv_, &attr);
|
||||||
SysAssert(ret == 0, "Couldn't initialize CV");
|
SysAssert(ret == 0, "Couldn't initialize CV");
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionVariableImpl::~ConditionVariableImpl()
|
ConditionVariableImpl::~ConditionVariableImpl()
|
||||||
{
|
{
|
||||||
pthread_cond_destroy(&pthreadCv_);
|
::pthread_cond_destroy(&this->pthreadCv_);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<IConditionMutex> ConditionVariableImpl::GetMutex()
|
AuSPtr<IConditionMutex> ConditionVariableImpl::GetMutex()
|
||||||
{
|
{
|
||||||
return mutex_;
|
return this->mutex_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConditionVariableImpl::WaitForSignal(AuUInt32 timeout)
|
bool ConditionVariableImpl::WaitForSignal(AuUInt32 timeout)
|
||||||
{
|
{
|
||||||
auto mutex = reinterpret_cast<pthread_mutex_t*>(mutex_->GetOSHandle());
|
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_->GetOSHandle());
|
||||||
|
|
||||||
if (gRuntimeRunLevel >= 5)
|
if (gRuntimeRunLevel >= 5)
|
||||||
{
|
{
|
||||||
@ -43,7 +48,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
int ret {};
|
int ret {};
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((ret = pthread_cond_wait(&pthreadCv_, mutex)) == 0)
|
if ((ret = ::pthread_cond_wait(&this->pthreadCv_, mutex)) == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -61,7 +66,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = pthread_cond_timedwait(&pthreadCv_, mutex, &tspec);
|
ret = ::pthread_cond_timedwait(&this->pthreadCv_, mutex, &tspec);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
@ -82,13 +87,13 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
void ConditionVariableImpl::Signal()
|
void ConditionVariableImpl::Signal()
|
||||||
{
|
{
|
||||||
auto ret = pthread_cond_signal(&pthreadCv_);
|
auto ret = ::pthread_cond_signal(&this->pthreadCv_);
|
||||||
SysAssert(ret == 0, "Couldn't wake any CV waiters");
|
SysAssert(ret == 0, "Couldn't wake any CV waiters");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConditionVariableImpl::Broadcast()
|
void ConditionVariableImpl::Broadcast()
|
||||||
{
|
{
|
||||||
auto ret = pthread_cond_broadcast(&pthreadCv_);
|
auto ret = ::pthread_cond_broadcast(&this->pthreadCv_);
|
||||||
SysAssert(ret == 0, "Couldn't wake any CV waiters");
|
SysAssert(ret == 0, "Couldn't wake any CV waiters");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
|
||||||
AuInt64 startTime = Time::CurrentClockMS();
|
AuInt64 startTime = Time::CurrentClockSteadyMS();
|
||||||
AuInt64 endTime = startTime + timeout;
|
AuInt64 endTime = startTime + timeout;
|
||||||
|
|
||||||
while (!AtomicIsEventSet())
|
while (!AtomicIsEventSet())
|
||||||
@ -42,7 +42,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
timeoutMs = endTime - static_cast<AuInt64>(Time::CurrentClockMS());
|
timeoutMs = endTime - static_cast<AuInt64>(Time::CurrentClockSteadyMS());
|
||||||
if (timeoutMs < 0)
|
if (timeoutMs < 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -15,9 +15,9 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
Mutex::Mutex()
|
Mutex::Mutex()
|
||||||
{
|
{
|
||||||
InitializeSRWLock(&atomicHolder_);
|
InitializeSRWLock(&this->atomicHolder_);
|
||||||
InitializeConditionVariable(&wakeup_);
|
InitializeConditionVariable(&this->wakeup_);
|
||||||
state_ = 0;
|
this->state_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex::~Mutex()
|
Mutex::~Mutex()
|
||||||
@ -32,7 +32,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool Mutex::TryLock()
|
bool Mutex::TryLock()
|
||||||
{
|
{
|
||||||
return _interlockedbittestandset(&state_, 0) == 0;
|
return _interlockedbittestandset(&this->state_, 0) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mutex::HasLockImplementation()
|
bool Mutex::HasLockImplementation()
|
||||||
@ -50,9 +50,9 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
bool returnValue = false;
|
bool returnValue = false;
|
||||||
|
|
||||||
AcquireSRWLockShared(&atomicHolder_);
|
AcquireSRWLockShared(&this->atomicHolder_);
|
||||||
|
|
||||||
AuInt64 startTime = Time::CurrentClockMS();
|
AuInt64 startTime = Time::CurrentClockSteadyMS();
|
||||||
AuInt64 endTime = startTime + timeout;
|
AuInt64 endTime = startTime + timeout;
|
||||||
|
|
||||||
BOOL status = false;
|
BOOL status = false;
|
||||||
@ -62,7 +62,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
if (timeout != 0)
|
if (timeout != 0)
|
||||||
{
|
{
|
||||||
startTime = Time::CurrentClockMS();
|
startTime = Time::CurrentClockSteadyMS();
|
||||||
if (startTime >= endTime)
|
if (startTime >= endTime)
|
||||||
{
|
{
|
||||||
goto exitWin32;
|
goto exitWin32;
|
||||||
@ -71,7 +71,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
timeoutMs = endTime - startTime;
|
timeoutMs = endTime - startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = SleepConditionVariableSRW(&wakeup_, &atomicHolder_, timeoutMs, CONDITION_VARIABLE_LOCKMODE_SHARED);
|
status = SleepConditionVariableSRW(&this->wakeup_, &this->atomicHolder_, timeoutMs, CONDITION_VARIABLE_LOCKMODE_SHARED);
|
||||||
if (!status)
|
if (!status)
|
||||||
{
|
{
|
||||||
SysAssertExp(GetLastError() == ERROR_TIMEOUT);
|
SysAssertExp(GetLastError() == ERROR_TIMEOUT);
|
||||||
@ -82,16 +82,16 @@ namespace Aurora::Threading::Primitives
|
|||||||
returnValue = true;
|
returnValue = true;
|
||||||
|
|
||||||
exitWin32:
|
exitWin32:
|
||||||
ReleaseSRWLockShared(&atomicHolder_);
|
ReleaseSRWLockShared(&this->atomicHolder_);
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Unlock()
|
void Mutex::Unlock()
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(&atomicHolder_);
|
AcquireSRWLockExclusive(&this->atomicHolder_);
|
||||||
state_ = 0;
|
this->state_ = 0;
|
||||||
ReleaseSRWLockExclusive(&atomicHolder_);
|
ReleaseSRWLockExclusive(&this->atomicHolder_);
|
||||||
WakeAllConditionVariable(&wakeup_);
|
WakeAllConditionVariable(&this->wakeup_);
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM IWaitable *MutexNew()
|
AUKN_SYM IWaitable *MutexNew()
|
||||||
|
@ -68,7 +68,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
Time::ms2tsabs(&tspec, timeout);
|
Time::ms2tsabsRealtime(&tspec, timeout);
|
||||||
|
|
||||||
int ret {};
|
int ret {};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool Semaphore::Lock(AuUInt64 timeout)
|
bool Semaphore::Lock(AuUInt64 timeout)
|
||||||
{
|
{
|
||||||
AuUInt64 start = AuTime::CurrentInternalClockMS();
|
AuUInt64 start = AuTime::CurrentClockSteadyMS();
|
||||||
AuUInt64 end = start + timeout;
|
AuUInt64 end = start + timeout;
|
||||||
|
|
||||||
AcquireSRWLockShared(&lock_); // we use atomics. using shared is fine, let's not get congested early
|
AcquireSRWLockShared(&lock_); // we use atomics. using shared is fine, let's not get congested early
|
||||||
@ -52,7 +52,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
if (timeout != 0)
|
if (timeout != 0)
|
||||||
{
|
{
|
||||||
start = Time::CurrentClockMS();
|
start = Time::CurrentClockSteadyMS();
|
||||||
if (start >= end)
|
if (start >= end)
|
||||||
{
|
{
|
||||||
ReleaseSRWLockShared(&this->lock_);
|
ReleaseSRWLockShared(&this->lock_);
|
||||||
|
@ -63,8 +63,9 @@ namespace Aurora::Threading::Primitives
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
Time::ms2tsabs(&tspec, timeout);
|
Time::ms2tsabsRealtime(&tspec, timeout);
|
||||||
|
|
||||||
|
//
|
||||||
int ret {};
|
int ret {};
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -4,12 +4,15 @@
|
|||||||
File: Clock.cpp
|
File: Clock.cpp
|
||||||
Date: 2021-6-13
|
Date: 2021-6-13
|
||||||
Author: Reece
|
Author: Reece
|
||||||
Note: Screw it, std::chrono has been widly shilled at C++11s answer to all these painful macros, asm linkage, and other shit youd have to do to pull clock
|
Note: Screw it, std::chrono has been widly shilled at C++11s answer to all these painful macros, asm linkage, and all the other bullshit that pulling clock counters entails.
|
||||||
Semantics have changed over time. I remember when, in 2016 or something like this, msvcs implementation of chrono kept breaking things.
|
Semantics can and will continue to change over time. I remember when, in 2016 or something like that, msvcs implementation of chrono kept changing in minor ways.
|
||||||
Every platform that remotely pretends to support a C++ toolchain has a chrono high performance clock. Any PC-like platform that uses clang and C++ more than likely uses a vendor hacked libc++ stl.
|
|
||||||
Seems portable enough. Worst case scenario, you're on a platform with a platform-specific high res clock function you could hack into here alongside portable timezone-unaware timegm/mktime functions somewhere else.
|
However, every platform that remotely pretends to support a C++ toolchain has a chrono high performance clock, and any PC-like platform that uses clang and C++ more than likely uses a vendor hacked liblibc++ stl.
|
||||||
There is so much quirky shit one has to deal with when relying on instruction cycle counters and other such instructions, plus cycle to ~time pred, plus forced + direction only, atop non-standard [sometimes inline]
|
The following should be portable enough. Worst case scenario, you're on a platform with a platform-specific high res clock function you could hack into here alongside portable timezone-unaware timegm/mktime functions linked somewhere else.
|
||||||
assembly, it's just not worth it to implement a CNTVCT_EL0 / RDSC / related userland client-app attempt of a high res clock.
|
|
||||||
|
There is so much quirky shit one has to deal with when relying on timestamp/cycle counters (cycle to ~time pred, plus positive delta, sometimes inlined assembly), it's just not worth it to
|
||||||
|
implement a CNTVCT_EL0 / RDSC / related interface ourselves.
|
||||||
|
|
||||||
I'll wave the white flag and use the STL in here for.now
|
I'll wave the white flag and use the STL in here for.now
|
||||||
***/
|
***/
|
||||||
#include <Source/RuntimeInternal.hpp>
|
#include <Source/RuntimeInternal.hpp>
|
||||||
@ -70,6 +73,7 @@ using high_res_clock = std::chrono::high_resolution_clock;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using sys_clock = std::chrono::system_clock;
|
using sys_clock = std::chrono::system_clock;
|
||||||
|
using steady_clock = std::chrono::steady_clock;
|
||||||
|
|
||||||
#if defined(AURORA_PLATFORM_WIN32)
|
#if defined(AURORA_PLATFORM_WIN32)
|
||||||
#define timegm _mkgmtime
|
#define timegm _mkgmtime
|
||||||
@ -155,6 +159,45 @@ namespace Aurora::Time
|
|||||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(NormalizeEpoch(sys_clock::now().time_since_epoch())).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 CurrentClockSteady()
|
||||||
|
{
|
||||||
|
return CurrentClockSteadyNS();
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 CurrentClockSteadyMS()
|
||||||
|
{
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
|
::timespec spec {};
|
||||||
|
if (::clock_getclock(CLOCK_MONOTONIC, &spec) == 0)
|
||||||
|
{
|
||||||
|
return AuSToMS<AuUInt64>(spec.tv_sec) + AuNSToMS<AuUInt64>(spec.tv_nsec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(high_res_clock::now().time_since_epoch()).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(steady_clock::now().time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
AUKN_SYM AuUInt64 CurrentClockSteadyNS()
|
||||||
|
{
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
|
::timespec spec {};
|
||||||
|
if (::clock_getclock(CLOCK_MONOTONIC, &spec) == 0)
|
||||||
|
{
|
||||||
|
return AuMSToNS<AuUInt64>(AuSToMS<AuUInt64>(spec.tv_sec)) + (AuUInt64)spec.tv_nsec;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||||
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(high_res_clock::now().time_since_epoch()).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(steady_clock::now().time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
AUKN_SYM AuInt64 CTimeToMS(time_t time)
|
AUKN_SYM AuInt64 CTimeToMS(time_t time)
|
||||||
{
|
{
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(sys_clock::from_time_t(time).time_since_epoch())).count();
|
return std::chrono::duration_cast<std::chrono::milliseconds>(NormalizeEpoch(sys_clock::from_time_t(time).time_since_epoch())).count();
|
||||||
@ -246,6 +289,22 @@ namespace Aurora::Time
|
|||||||
{
|
{
|
||||||
return frequency;
|
return frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(AURORA_COMPILER_MSVC)
|
||||||
|
return frequency = _Query_perf_frequency();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
|
::timespec spec {};
|
||||||
|
if (::clock_getres(CLOCK_MONOTONIC, &spec) == 0)
|
||||||
|
{
|
||||||
|
if (spec.tv_nsec && !spec.tv_sec)
|
||||||
|
{
|
||||||
|
return frequency = 1000000000ull / spec.tv_nsec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return frequency = static_cast<double>(high_res_clock::period::den) / static_cast<double>(high_res_clock::period::num);
|
return frequency = static_cast<double>(high_res_clock::period::den) / static_cast<double>(high_res_clock::period::num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,18 @@ namespace Aurora::Time
|
|||||||
|
|
||||||
static void ms2tsabs(struct timespec *ts, unsigned long ms)
|
static void ms2tsabs(struct timespec *ts, unsigned long ms)
|
||||||
{
|
{
|
||||||
clock_gettime(CLOCK_REALTIME, ts);
|
::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 baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts->tv_nsec;
|
||||||
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
||||||
@ -80,7 +91,7 @@ namespace Aurora::Time
|
|||||||
static void ms2tvabs(struct timeval *tv, unsigned long ms)
|
static void ms2tvabs(struct timeval *tv, unsigned long ms)
|
||||||
{
|
{
|
||||||
timespec ts;
|
timespec ts;
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
::clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
|
||||||
auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts.tv_nsec;
|
auto baseNS = ((AuUInt64)ms * (AuUInt64)1'000'000) + (AuUInt64)ts.tv_nsec;
|
||||||
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
auto remainderNS = (AuUInt64)baseNS % (AuUInt64)1'000'000'000;
|
||||||
|
Loading…
Reference in New Issue
Block a user