From 591c0fe48b0cb4f4b843675dda7bee7e81e5d818 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sun, 22 Oct 2023 06:11:39 +0100 Subject: [PATCH] [+] ILSSemaphore::AddMany --- Include/Aurora/IO/Loop/Loop.hpp | 1 + Source/IO/IPC/AuIPCPrimitives.Linux.cpp | 5 +++ Source/IO/IPC/AuIPCPrimitives.Linux.hpp | 1 + Source/IO/IPC/AuIPCPrimitives.NT.cpp | 7 ++++ Source/IO/Loop/LSLocalSemaphore.cpp | 48 ++++++++++++------------- Source/IO/Loop/LSLocalSemaphore.hpp | 3 +- Source/IO/Loop/LSSemaphore.Linux.cpp | 15 +++++++- Source/IO/Loop/LSSemaphore.Linux.hpp | 2 ++ Source/IO/Loop/LSSemaphore.NT.cpp | 6 ++++ Source/IO/Loop/LSSemaphore.NT.hpp | 1 + 10 files changed, 62 insertions(+), 27 deletions(-) diff --git a/Include/Aurora/IO/Loop/Loop.hpp b/Include/Aurora/IO/Loop/Loop.hpp index 9092551b..11a354c9 100644 --- a/Include/Aurora/IO/Loop/Loop.hpp +++ b/Include/Aurora/IO/Loop/Loop.hpp @@ -27,6 +27,7 @@ namespace Aurora::IO::Loop struct ILSSemaphore : virtual ILoopSource { virtual bool AddOne() = 0; + virtual bool AddMany(AuUInt32 uCount) = 0; }; struct ILSEvent : virtual ILoopSource diff --git a/Source/IO/IPC/AuIPCPrimitives.Linux.cpp b/Source/IO/IPC/AuIPCPrimitives.Linux.cpp index fa406aa1..1dc3329c 100644 --- a/Source/IO/IPC/AuIPCPrimitives.Linux.cpp +++ b/Source/IO/IPC/AuIPCPrimitives.Linux.cpp @@ -205,6 +205,11 @@ namespace Aurora::IO::IPC return this->semaphore_.AddOne(); } + bool IPCSemaphoreProxy::AddMany(AuUInt32 uCount) + { + return this->semaphore_.AddMany(uCount); + } + bool IPCSemaphoreProxy::IsSignaled() { return this->semaphore_.IsSignaled(); diff --git a/Source/IO/IPC/AuIPCPrimitives.Linux.hpp b/Source/IO/IPC/AuIPCPrimitives.Linux.hpp index 59ce1160..ae198886 100644 --- a/Source/IO/IPC/AuIPCPrimitives.Linux.hpp +++ b/Source/IO/IPC/AuIPCPrimitives.Linux.hpp @@ -59,6 +59,7 @@ namespace Aurora::IO::IPC IMPLEMENT_HANDLE bool AddOne() override; + bool AddMany(AuUInt32 uCount) override; bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; diff --git a/Source/IO/IPC/AuIPCPrimitives.NT.cpp b/Source/IO/IPC/AuIPCPrimitives.NT.cpp index 420261cb..f17643d4 100644 --- a/Source/IO/IPC/AuIPCPrimitives.NT.cpp +++ b/Source/IO/IPC/AuIPCPrimitives.NT.cpp @@ -267,6 +267,8 @@ namespace Aurora::IO::IPC IMPLEMENT_HANDLE bool AddOne() override; + bool AddMany(AuUInt32 uCount) override; + bool IsSignaled() override; bool WaitOn(AuUInt32 timeout) override; @@ -292,6 +294,11 @@ namespace Aurora::IO::IPC return this->semaphore_.AddOne(); } + bool IPCSemaphoreProxy::AddMany(AuUInt32 uCount) + { + return this->semaphore_.AddMany(uCount); + } + bool IPCSemaphoreProxy::IsSignaled() { return this->semaphore_.IsSignaled(); diff --git a/Source/IO/Loop/LSLocalSemaphore.cpp b/Source/IO/Loop/LSLocalSemaphore.cpp index 8695f4a2..3572dfe9 100644 --- a/Source/IO/Loop/LSLocalSemaphore.cpp +++ b/Source/IO/Loop/LSLocalSemaphore.cpp @@ -23,13 +23,13 @@ namespace Aurora::IO::Loop bool LSLocalSemaphore::TryInit(AuUInt32 initialCount) { - if (!LSSemaphore::TryInit(1)) + if (!LSSemaphore::TryInit(initialCount)) { return false; } this->uAtomicSemaphore = initialCount; - this->uAtomicWord = 1; + this->uAtomicKernelSemaphore = initialCount; return true; } @@ -40,25 +40,22 @@ namespace Aurora::IO::Loop while (true) { - auto uOld = this->uAtomicWord; + auto uOld = this->uAtomicKernelSemaphore; if (uOld == 0) { break; } - if (AuAtomicCompareExchange(&this->uAtomicWord, uOld - 1, uOld) == uOld) + if (AuAtomicCompareExchange(&this->uAtomicKernelSemaphore, uOld - 1, uOld) == uOld) { auto uCount = AuAtomicLoad(&this->uAtomicSemaphore); if (uOld - 1 == 0 && uCount) { - AuAtomicAdd(&this->uAtomicWord, uCount); - for (AU_ITERATE_N(i, uCount)) - { - LSSemaphore::AddOne(); - } + AuAtomicAdd(&this->uAtomicKernelSemaphore, uCount); + LSSemaphore::AddMany(uCount); } break; @@ -72,16 +69,30 @@ namespace Aurora::IO::Loop { auto uNext = AuAtomicAdd(&this->uAtomicSemaphore, 1u); - if (AuAtomicLoad(&this->uAtomicWord) >= uNext) + if (AuAtomicLoad(&this->uAtomicKernelSemaphore) >= uNext) { return true; } - AuAtomicAdd(&this->uAtomicWord, 1u); + AuAtomicAdd(&this->uAtomicKernelSemaphore, 1u); LSSemaphore::AddOne(); return true; } + bool LSLocalSemaphore::AddMany(AuUInt32 uCount) + { + auto uNext = AuAtomicAdd(&this->uAtomicSemaphore, 1u); + + if (AuAtomicLoad(&this->uAtomicKernelSemaphore) >= uNext) + { + return true; + } + + AuAtomicAdd(&this->uAtomicKernelSemaphore, uCount); + LSSemaphore::AddMany(uCount); + return true; + } + bool LSLocalSemaphore::IsSignaled() { return this->TryTake(); @@ -165,25 +176,12 @@ namespace Aurora::IO::Loop void LSLocalSemaphore::OnPresleep() { - #if 0 - while (auto uActiveSemaphore = AuAtomicLoad(&this->uAtomicSemaphore)) - { - if (AuAtomicLoad(&this->uAtomicWord) >= uActiveSemaphore) - { - return; - } - AuAtomicAdd(&this->uAtomicWord, uActiveSemaphore); - for (AU_ITERATE_N(i, uActiveSemaphore)) - { - LSSemaphore::AddOne(); - } - } - #endif } void LSLocalSemaphore::OnFinishSleep() { + } AUKN_SYM AuSPtr NewLSSemaphore(AuUInt32 initialCount) diff --git a/Source/IO/Loop/LSLocalSemaphore.hpp b/Source/IO/Loop/LSLocalSemaphore.hpp index 1430a199..01802c50 100644 --- a/Source/IO/Loop/LSLocalSemaphore.hpp +++ b/Source/IO/Loop/LSLocalSemaphore.hpp @@ -23,6 +23,7 @@ namespace Aurora::IO::Loop ELoopSource GetType() override; bool AddOne() override; + bool AddMany(AuUInt32 uCount); virtual bool OnTrigger(AuUInt handle) override; @@ -35,6 +36,6 @@ namespace Aurora::IO::Loop void OnFinishSleep() override; AuAUInt32 uAtomicSemaphore {}; - AuAUInt32 uAtomicWord {}; + AuAUInt32 uAtomicKernelSemaphore {}; }; } \ No newline at end of file diff --git a/Source/IO/Loop/LSSemaphore.Linux.cpp b/Source/IO/Loop/LSSemaphore.Linux.cpp index 6e098d84..c3c2d555 100644 --- a/Source/IO/Loop/LSSemaphore.Linux.cpp +++ b/Source/IO/Loop/LSSemaphore.Linux.cpp @@ -54,7 +54,20 @@ namespace Aurora::IO::Loop bool LSSemaphore::AddOne() { - AuUInt64 plsNoOverflow {1}; + AuUInt64 plsNoOverflow { 1 }; + + if (::write(this->handle, &plsNoOverflow, sizeof(plsNoOverflow)) != 8) + { + // todo push error + return false; + } + + return true; + } + + bool LSSemaphore::AddMany(AuUInt32 uCount) + { + AuUInt64 plsNoOverflow { uCount }; if (::write(this->handle, &plsNoOverflow, sizeof(plsNoOverflow)) != 8) { diff --git a/Source/IO/Loop/LSSemaphore.Linux.hpp b/Source/IO/Loop/LSSemaphore.Linux.hpp index e2ef25fe..864a6c6e 100644 --- a/Source/IO/Loop/LSSemaphore.Linux.hpp +++ b/Source/IO/Loop/LSSemaphore.Linux.hpp @@ -20,6 +20,8 @@ namespace Aurora::IO::Loop bool TryInit(AuUInt32 initialCount = 0); bool AddOne() override; + bool AddMany(AuUInt32 uCount) override; + virtual bool OnTrigger(AuUInt handle) override; diff --git a/Source/IO/Loop/LSSemaphore.NT.cpp b/Source/IO/Loop/LSSemaphore.NT.cpp index ae8475f5..2272a964 100644 --- a/Source/IO/Loop/LSSemaphore.NT.cpp +++ b/Source/IO/Loop/LSSemaphore.NT.cpp @@ -29,6 +29,12 @@ namespace Aurora::IO::Loop return ::ReleaseSemaphore(AuReinterpretCast(handle), 1, &atomicOld); } + bool LSSemaphore::AddMany(AuUInt32 uCount) + { + LONG atomicOld; + return ::ReleaseSemaphore(AuReinterpretCast(handle), uCount, &atomicOld); + } + bool LSSemaphore::IsSignaled() { return LSHandle::IsSignaled(); diff --git a/Source/IO/Loop/LSSemaphore.NT.hpp b/Source/IO/Loop/LSSemaphore.NT.hpp index 08fb94e5..91c9dff5 100644 --- a/Source/IO/Loop/LSSemaphore.NT.hpp +++ b/Source/IO/Loop/LSSemaphore.NT.hpp @@ -19,6 +19,7 @@ namespace Aurora::IO::Loop bool TryInit(AuUInt32 initialCount = 0); bool AddOne() override; + bool AddMany(AuUInt32 uCount) override; bool ILSSemaphore::IsSignaled() override; bool ILSSemaphore::WaitOn(AuUInt32 timeout) override;