From f05cafbff7e727d7b76b3b8120685e71d3916492 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Fri, 1 Dec 2023 10:33:55 +0000 Subject: [PATCH] [*] Win32 loopqueue optimization --- Source/IO/IPC/AuIPCMutexFutex.Linux.cpp | 5 +++++ Source/IO/IPC/AuIPCMutexFutex.Linux.hpp | 1 + Source/IO/IPC/AuIPCPrimitives.Linux.cpp | 10 ++++++++++ Source/IO/IPC/AuIPCPrimitives.Linux.hpp | 2 ++ Source/IO/IPC/AuIPCPrimitives.NT.cpp | 19 ++++++++++++++++++- Source/IO/Loop/ILoopSourceEx.hpp | 1 + Source/IO/Loop/LSLocalEvent.cpp | 7 ++++++- Source/IO/Loop/LSLocalEvent.hpp | 1 + Source/IO/Loop/LSLocalMutex.cpp | 7 ++++++- Source/IO/Loop/LSLocalMutex.hpp | 1 + Source/IO/Loop/LSLocalSemaphore.cpp | 7 ++++++- Source/IO/Loop/LSLocalSemaphore.hpp | 1 + Source/IO/Loop/LoopQueue.NT.cpp | 12 +++++++----- Source/IO/Loop/WaitSingleBase.cpp | 5 +++++ Source/IO/Loop/WaitSingleBase.hpp | 1 + Source/IO/Net/AuNetAdapter.cpp | 2 ++ 16 files changed, 73 insertions(+), 9 deletions(-) diff --git a/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp b/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp index b36f9b23..e27c8665 100644 --- a/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp +++ b/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp @@ -528,6 +528,11 @@ namespace Aurora::IO::IPC return true; } + bool IPCMutexProxy::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + bool IPCMutexProxy::WaitOn(AuUInt32 timeout) { auto futex = this->GetFutex(); diff --git a/Source/IO/IPC/AuIPCMutexFutex.Linux.hpp b/Source/IO/IPC/AuIPCMutexFutex.Linux.hpp index d335b528..ea45eb3b 100644 --- a/Source/IO/IPC/AuIPCMutexFutex.Linux.hpp +++ b/Source/IO/IPC/AuIPCMutexFutex.Linux.hpp @@ -23,6 +23,7 @@ namespace Aurora::IO::IPC bool Unlock() override; + bool IsSignaledNoSpinIfUserland() override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; Loop::ELoopSource GetType() override; diff --git a/Source/IO/IPC/AuIPCPrimitives.Linux.cpp b/Source/IO/IPC/AuIPCPrimitives.Linux.cpp index 1dc3329c..05d99a91 100644 --- a/Source/IO/IPC/AuIPCPrimitives.Linux.cpp +++ b/Source/IO/IPC/AuIPCPrimitives.Linux.cpp @@ -89,6 +89,11 @@ namespace Aurora::IO::IPC return this->event_.GetType(); } + bool IPCEventProxy::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + AUKN_SYM AuSPtr NewEvent(bool triggered, bool atomicRelease) { auto object = AuMakeShared(triggered, atomicRelease); @@ -215,6 +220,11 @@ namespace Aurora::IO::IPC return this->semaphore_.IsSignaled(); } + bool IPCSemaphoreProxy::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + bool IPCSemaphoreProxy::WaitOn(AuUInt32 timeout) { return this->semaphore_.WaitOn(timeout); diff --git a/Source/IO/IPC/AuIPCPrimitives.Linux.hpp b/Source/IO/IPC/AuIPCPrimitives.Linux.hpp index ae198886..9973c8bb 100644 --- a/Source/IO/IPC/AuIPCPrimitives.Linux.hpp +++ b/Source/IO/IPC/AuIPCPrimitives.Linux.hpp @@ -41,6 +41,7 @@ namespace Aurora::IO::IPC bool Set() override; bool Reset() override; + bool IsSignaledNoSpinIfUserland() override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; Loop::ELoopSource GetType() override; @@ -61,6 +62,7 @@ namespace Aurora::IO::IPC bool AddOne() override; bool AddMany(AuUInt32 uCount) override; + bool IsSignaledNoSpinIfUserland() override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; Loop::ELoopSource GetType() override; diff --git a/Source/IO/IPC/AuIPCPrimitives.NT.cpp b/Source/IO/IPC/AuIPCPrimitives.NT.cpp index f17643d4..c634f19e 100644 --- a/Source/IO/IPC/AuIPCPrimitives.NT.cpp +++ b/Source/IO/IPC/AuIPCPrimitives.NT.cpp @@ -37,6 +37,7 @@ namespace Aurora::IO::IPC bool Unlock() override; + bool IsSignaledNoSpinIfUserland() override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; Loop::ELoopSource GetType() override; @@ -63,6 +64,11 @@ namespace Aurora::IO::IPC return this->mutex_.IsSignaled(); } + bool IPCMutexProxy::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + bool IPCMutexProxy::WaitOn(AuUInt32 timeout) { return this->mutex_.WaitOn(timeout); @@ -150,6 +156,7 @@ namespace Aurora::IO::IPC bool Set() override; bool Reset() override; + bool IsSignaledNoSpinIfUserland() override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; Loop::ELoopSource GetType() override; @@ -191,6 +198,11 @@ namespace Aurora::IO::IPC return this->event_.GetType(); } + bool IPCEventProxy::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + AUKN_SYM AuSPtr NewEvent(bool triggered, bool atomicRelease) { IPC::IPCHandle handle; @@ -269,7 +281,7 @@ namespace Aurora::IO::IPC bool AddOne() override; bool AddMany(AuUInt32 uCount) override; - + bool IsSignaledNoSpinIfUserland() override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; Loop::ELoopSource GetType() override; @@ -304,6 +316,11 @@ namespace Aurora::IO::IPC return this->semaphore_.IsSignaled(); } + bool IPCSemaphoreProxy::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + bool IPCSemaphoreProxy::WaitOn(AuUInt32 timeout) { return this->semaphore_.WaitOn(timeout); diff --git a/Source/IO/Loop/ILoopSourceEx.hpp b/Source/IO/Loop/ILoopSourceEx.hpp index 55b045ea..f495908b 100644 --- a/Source/IO/Loop/ILoopSourceEx.hpp +++ b/Source/IO/Loop/ILoopSourceEx.hpp @@ -11,6 +11,7 @@ namespace Aurora::IO::Loop { struct ILoopSourceEx : virtual ILoopSource { + virtual bool IsSignaledNoSpinIfUserland() = 0; virtual void OnPresleep() = 0; virtual bool OnTrigger(AuUInt handle) = 0; virtual void OnFinishSleep() = 0; diff --git a/Source/IO/Loop/LSLocalEvent.cpp b/Source/IO/Loop/LSLocalEvent.cpp index 9e5838ea..9811883e 100644 --- a/Source/IO/Loop/LSLocalEvent.cpp +++ b/Source/IO/Loop/LSLocalEvent.cpp @@ -196,11 +196,16 @@ namespace Aurora::IO::Loop }); } - bool LSLocalEvent::TryTake() + bool LSLocalEvent::IsSignaledNoSpinIfUserland() { return this->TryTakeNoSpin(); } + bool LSLocalEvent::TryTake() + { + return this->TryTakeSpin(); + } + bool LSLocalEvent::TryTakeWaitMS(AuUInt32 timeout) { auto uEndTime = AuTime::SteadyClockNS() + AuMSToNS(timeout); diff --git a/Source/IO/Loop/LSLocalEvent.hpp b/Source/IO/Loop/LSLocalEvent.hpp index 41f32a92..0ec367b2 100644 --- a/Source/IO/Loop/LSLocalEvent.hpp +++ b/Source/IO/Loop/LSLocalEvent.hpp @@ -32,6 +32,7 @@ namespace Aurora::IO::Loop bool TryTake(); bool TryTakeWaitMS(AuUInt32 timeout); + bool IsSignaledNoSpinIfUserland() override; void OnPresleep() override; void OnFinishSleep() override; diff --git a/Source/IO/Loop/LSLocalMutex.cpp b/Source/IO/Loop/LSLocalMutex.cpp index 6e81aa1e..fbcc683b 100644 --- a/Source/IO/Loop/LSLocalMutex.cpp +++ b/Source/IO/Loop/LSLocalMutex.cpp @@ -85,6 +85,11 @@ namespace Aurora::IO::Loop return this->TryTake(); } + bool LSLocalMutex::IsSignaledNoSpinIfUserland() + { + return this->TryTakeNoSpin(); + } + bool LSLocalMutex::WaitOn(AuUInt32 timeout) { return this->TryTakeWaitMS(timeout); @@ -110,7 +115,7 @@ namespace Aurora::IO::Loop bool LSLocalMutex::TryTake() { - return TryTakeNoSpin(); + return this->TryTakeSpin(); } bool LSLocalMutex::TryTakeWaitMS(AuUInt32 timeout) diff --git a/Source/IO/Loop/LSLocalMutex.hpp b/Source/IO/Loop/LSLocalMutex.hpp index 6e481527..4c95babc 100644 --- a/Source/IO/Loop/LSLocalMutex.hpp +++ b/Source/IO/Loop/LSLocalMutex.hpp @@ -19,6 +19,7 @@ namespace Aurora::IO::Loop bool TryInit(); bool IsSignaled() override; + bool IsSignaledNoSpinIfUserland() override; bool WaitOn(AuUInt32 timeout) override; ELoopSource GetType() override; diff --git a/Source/IO/Loop/LSLocalSemaphore.cpp b/Source/IO/Loop/LSLocalSemaphore.cpp index ada2f014..70d96fd0 100644 --- a/Source/IO/Loop/LSLocalSemaphore.cpp +++ b/Source/IO/Loop/LSLocalSemaphore.cpp @@ -98,6 +98,11 @@ namespace Aurora::IO::Loop return this->TryTake(); } + bool LSLocalSemaphore::IsSignaledNoSpinIfUserland() + { + return this->TryTakeNoSpin(); + } + bool LSLocalSemaphore::WaitOn(AuUInt32 timeout) { return this->TryTakeWaitMS(timeout); @@ -133,7 +138,7 @@ namespace Aurora::IO::Loop bool LSLocalSemaphore::TryTake() { - return this->TryTakeNoSpin(); + return this->TryTakeSpin(); } bool LSLocalSemaphore::TryTakeWaitMS(AuUInt32 timeout) diff --git a/Source/IO/Loop/LSLocalSemaphore.hpp b/Source/IO/Loop/LSLocalSemaphore.hpp index 01802c50..c58622cd 100644 --- a/Source/IO/Loop/LSLocalSemaphore.hpp +++ b/Source/IO/Loop/LSLocalSemaphore.hpp @@ -20,6 +20,7 @@ namespace Aurora::IO::Loop bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; + bool IsSignaledNoSpinIfUserland() override; ELoopSource GetType() override; bool AddOne() override; diff --git a/Source/IO/Loop/LoopQueue.NT.cpp b/Source/IO/Loop/LoopQueue.NT.cpp index b7a33b3e..8f5bae38 100644 --- a/Source/IO/Loop/LoopQueue.NT.cpp +++ b/Source/IO/Loop/LoopQueue.NT.cpp @@ -1177,6 +1177,8 @@ namespace Aurora::IO::Loop bool singular = source.source->Singular(); bool bPollTriggered = this->handleArrayOr_[queueIterator.startingIndexOr] == this->hDummy_; + bool bAltTrigger {}; + if (!bPollTriggered) { if (!singular) @@ -1184,10 +1186,10 @@ namespace Aurora::IO::Loop for (const auto &handle : source.source->GetHandles()) { if ((firstTriggered == handle) || - (::WaitForSingleObject(reinterpret_cast(handle), 0) == WAIT_OBJECT_0)) + (bAltTrigger = source.source->IsSignaledNoSpinIfUserland())) { lastHandle = handle; - wasTriggered = true; + wasTriggered = !bAltTrigger; break; } } @@ -1196,15 +1198,15 @@ namespace Aurora::IO::Loop { auto handle = source.source->GetHandle(); if ((firstTriggered == handle) || - (::WaitForSingleObject(reinterpret_cast(handle), 0) == WAIT_OBJECT_0)) + (bAltTrigger = source.source->IsSignaledNoSpinIfUserland())) { lastHandle = firstTriggered; - wasTriggered = true; + wasTriggered = !bAltTrigger; } } } - if (bPollTriggered || (wasTriggered && source.source->OnTrigger(lastHandle))) + if (bPollTriggered || (bAltTrigger) || (wasTriggered && source.source->OnTrigger(lastHandle))) { bool failing {}; diff --git a/Source/IO/Loop/WaitSingleBase.cpp b/Source/IO/Loop/WaitSingleBase.cpp index 2251afcf..45b9a2f6 100644 --- a/Source/IO/Loop/WaitSingleBase.cpp +++ b/Source/IO/Loop/WaitSingleBase.cpp @@ -10,6 +10,11 @@ namespace Aurora::IO::Loop { + bool WaitSingleBase::IsSignaledNoSpinIfUserland() + { + return this->IsSignaled(); + } + bool WaitSingleBase::IsSignaled() { bool val {}; diff --git a/Source/IO/Loop/WaitSingleBase.hpp b/Source/IO/Loop/WaitSingleBase.hpp index f1f11164..a62481a7 100644 --- a/Source/IO/Loop/WaitSingleBase.hpp +++ b/Source/IO/Loop/WaitSingleBase.hpp @@ -29,6 +29,7 @@ namespace Aurora::IO::Loop struct WaitSingleBase : virtual ILoopSourceEx { + virtual bool IsSignaledNoSpinIfUserland() override; virtual bool IsSignaled() override; virtual bool WaitOn(AuUInt32 timeout) override; diff --git a/Source/IO/Net/AuNetAdapter.cpp b/Source/IO/Net/AuNetAdapter.cpp index 3d34f15a..a84b5f38 100644 --- a/Source/IO/Net/AuNetAdapter.cpp +++ b/Source/IO/Net/AuNetAdapter.cpp @@ -18,6 +18,8 @@ namespace Aurora::IO::Net IPAddress NetAdapter::ToAddress() { + AuMemory::GetDefaultDiscontiguousHeapShared()->NewClass(); + return this->address; }