[*] Change how the default work completion group for an AuAsync threads is created and kept alive

This commit is contained in:
Reece Wilson 2024-07-12 20:40:05 +01:00
parent af5c8e86c0
commit 46ef3231a2
7 changed files with 130 additions and 21 deletions

View File

@ -72,6 +72,12 @@ namespace Aurora::Async
return true; return true;
} }
void ThreadStateBase::Deinit()
{
AuResetMember(this->singletons);
}
void ThreadStateSync::SetEvent(bool bBoth, bool bHasWork) void ThreadStateSync::SetEvent(bool bBoth, bool bHasWork)
{ {
if (bHasWork) if (bHasWork)

View File

@ -76,5 +76,6 @@ namespace Aurora::Async
ThreadStateSingletons singletons; ThreadStateSingletons singletons;
bool Init(); bool Init();
void Deinit();
}; };
} }

View File

@ -7,6 +7,7 @@
***/ ***/
#include <Source/RuntimeInternal.hpp> #include <Source/RuntimeInternal.hpp>
#include "AuThreadStateSingletons.hpp" #include "AuThreadStateSingletons.hpp"
#include <Source/IO/CompletionGroup/CompletionGroup.hpp>
namespace Aurora::Async namespace Aurora::Async
{ {
@ -29,7 +30,7 @@ namespace Aurora::Async
} }
} }
AuSPtr<AuIO::CompletionGroup::ICompletionGroup> ThreadStateSingletons::GetIOGroup() AuSPtr<AuIO::CompletionGroup::ICompletionGroup> ThreadStateSingletons::GetIOGroup(AuWorkerPId_t pid)
{ {
if (this->pGroup) if (this->pGroup)
{ {
@ -44,7 +45,16 @@ namespace Aurora::Async
return this->pGroup; return this->pGroup;
} }
return this->pGroup = AuIO::CompletionGroup::NewCompletionGroup(); this->pGroup = AuIO::CompletionGroup::NewCompletionGroup();
if (!this->pGroup)
{
return {};
}
AuStaticCast<IO::CompletionGroup::CompletionGroup>(this->pGroup)->MakeInternalAsync(pid);
return this->pGroup;
} }
} }

View File

@ -22,7 +22,7 @@ namespace Aurora::Async
AuSPtr<AuIO::Net::INetWorker> pNetWorker; AuSPtr<AuIO::Net::INetWorker> pNetWorker;
AuSPtr<AuIO::CompletionGroup::ICompletionGroup> pGroup; AuSPtr<AuIO::CompletionGroup::ICompletionGroup> pGroup;
AuSPtr<AuIO::CompletionGroup::ICompletionGroup> GetIOGroup(); AuSPtr<AuIO::CompletionGroup::ICompletionGroup> GetIOGroup(AuWorkerPId_t pid);
AuSPtr<AuIO::IIOProcessor> GetIOProcessor(AuWorkerPId_t pid); AuSPtr<AuIO::IIOProcessor> GetIOProcessor(AuWorkerPId_t pid);
AuSPtr<AuIO::Net::INetInterface> GetIONetInterface(AuWorkerPId_t pid); AuSPtr<AuIO::Net::INetInterface> GetIONetInterface(AuWorkerPId_t pid);
AuSPtr<AuIO::Net::INetWorker> GetIONetWorker(AuWorkerPId_t pid); AuSPtr<AuIO::Net::INetWorker> GetIONetWorker(AuWorkerPId_t pid);

View File

@ -801,11 +801,11 @@ namespace Aurora::Async
return tlsWorkerId; return tlsWorkerId;
} }
AuSPtr<AuIO::IIOProcessor> ThreadPool::GetIOProcessor(WorkerId_t pid) AuSPtr<AuIO::IIOProcessor> ThreadPool::GetIOProcessor(WorkerId_t id)
{ {
if (auto pState = this->GetThreadHandle(pid)) if (auto pState = this->GetThreadHandle(id))
{ {
return pState->singletons.GetIOProcessor({ this->SharedFromThis(), pid }); return pState->singletons.GetIOProcessor({ this->SharedFromThis(), id });
} }
return {}; return {};
@ -815,27 +815,27 @@ namespace Aurora::Async
{ {
if (auto pState = this->GetThreadHandle(id)) if (auto pState = this->GetThreadHandle(id))
{ {
return pState->singletons.GetIOGroup(); return pState->singletons.GetIOGroup({ this->SharedFromThis(), id });
} }
return {}; return {};
} }
AuSPtr<AuIO::Net::INetInterface> ThreadPool::GetIONetInterface(WorkerId_t pid) AuSPtr<AuIO::Net::INetInterface> ThreadPool::GetIONetInterface(WorkerId_t id)
{ {
if (auto pState = this->GetThreadHandle(pid)) if (auto pState = this->GetThreadHandle(id))
{ {
return pState->singletons.GetIONetInterface({ this->SharedFromThis(), pid }); return pState->singletons.GetIONetInterface({ this->SharedFromThis(), id });
} }
return {}; return {};
} }
AuSPtr<AuIO::Net::INetWorker> ThreadPool::GetIONetWorker(WorkerId_t pid) AuSPtr<AuIO::Net::INetWorker> ThreadPool::GetIONetWorker(WorkerId_t id)
{ {
if (auto pState = this->GetThreadHandle(pid)) if (auto pState = this->GetThreadHandle(id))
{ {
return pState->singletons.GetIONetWorker({ this->SharedFromThis(), pid }); return pState->singletons.GetIONetWorker({ this->SharedFromThis(), id });
} }
return {}; return {};
@ -1418,6 +1418,8 @@ namespace Aurora::Async
{ {
state->Decommit(id.second); state->Decommit(id.second);
} }
pLocalState->Deinit();
} }
AuSPtr<GroupState> ThreadPool::GetGroup(ThreadGroup_t type) AuSPtr<GroupState> ThreadPool::GetGroup(ThreadGroup_t type)

View File

@ -186,6 +186,8 @@ namespace Aurora::IO::CompletionGroup
// anyone else? // anyone else?
this->ResetMemoryPins(); this->ResetMemoryPins();
} }
this->TryCollectInternal();
} }
void CompletionGroup::AddWorkItem(const AuSPtr<ICompletionGroupWorkItem> &pCompletable) void CompletionGroup::AddWorkItem(const AuSPtr<ICompletionGroupWorkItem> &pCompletable)
@ -194,6 +196,7 @@ namespace Aurora::IO::CompletionGroup
AU_LOCK_GUARD(this->mutex); AU_LOCK_GUARD(this->mutex);
this->workItems.push_back(pCompletable); this->workItems.push_back(pCompletable);
AuAtomicAdd(&this->uAdded, 1u); AuAtomicAdd(&this->uAdded, 1u);
this->TryCreateInternal();
} }
void CompletionGroup::UnsafeRemoveItem(const AuSPtr<ICompletionGroupWorkItem> &pCompletable) void CompletionGroup::UnsafeRemoveItem(const AuSPtr<ICompletionGroupWorkItem> &pCompletable)
@ -335,15 +338,8 @@ namespace Aurora::IO::CompletionGroup
AuResetMember(this->pAndBarrier); AuResetMember(this->pAndBarrier);
} }
AuSPtr<AuAsync::IWorkItem> CompletionGroup::OnSingleCompletion() AuSPtr<AuAsync::IWorkItem> CompletionGroup::OnSingleCompletionIntl()
{ {
AU_LOCK_GUARD(this->cs);
if (this->pAnyBarrier)
{
return this->pAnyBarrier;
}
if (this->bNoAny) if (this->bNoAny)
{ {
SysPushErrorGeneric("To prevent double LoopQueue::SourceAdd on the same source, you must not call ::OnSingleCompletion() after ::OnCompletion() in this specific order"); SysPushErrorGeneric("To prevent double LoopQueue::SourceAdd on the same source, you must not call ::OnSingleCompletion() after ::OnCompletion() in this specific order");
@ -362,6 +358,93 @@ namespace Aurora::IO::CompletionGroup
return pRet; return pRet;
} }
AuSPtr<AuAsync::IWorkItem> CompletionGroup::OnSingleCompletion()
{
AU_LOCK_GUARD(this->cs);
if (this->pAnyBarrier)
{
return this->pAnyBarrier;
}
if (this->pAnyBarrierInternal)
{
return this->pAnyBarrierInternal;
}
if (this->workerId)
{
TryCreateInternal();
return this->pAnyBarrierInternal;
}
else
{
return this->pAnyBarrier = OnSingleCompletionIntl();
}
}
void CompletionGroup::TryCreateInternal()
{
if (!this->workerId)
{
return;
}
if (this->pAnyBarrierInternal)
{
return;
}
if (this->workerId != AuAsync::GetCurrentWorkerPId())
{
return;
}
this->pAnyBarrierInternal = OnSingleCompletionIntl();
this->SetNeverEnding(true);
if (auto pKernel = this->workerId.GetPool()->ToKernelWorkQueue(this->workerId))
{
(void)pKernel->Commit();
}
}
void CompletionGroup::TryCollectInternal()
{
if (!this->workItems.empty())
{
return;
}
if (!this->workerId)
{
return;
}
if (!this->pAnyBarrierInternal)
{
return;
}
if (this->workerId != AuAsync::GetCurrentWorkerPId())
{
return;
}
AuResetMember(this->pAnyBarrierInternal);
if (auto pKernel = this->workerId.GetPool()->ToKernelWorkQueue(this->workerId))
{
(void)pKernel->Commit();
}
}
void CompletionGroup::MakeInternalAsync(AuWorkerID pid)
{
this->SetNeverEnding(true);
this->workerId = pid;
}
AUKN_SYM AuSPtr<ICompletionGroup> NewCompletionGroup() AUKN_SYM AuSPtr<ICompletionGroup> NewCompletionGroup()
{ {
return AuMakeShared<CompletionGroup>(); return AuMakeShared<CompletionGroup>();

View File

@ -23,6 +23,9 @@ namespace Aurora::IO::CompletionGroup
AuSPtr<AuAsync::IWorkItem> OnCompletion() override; AuSPtr<AuAsync::IWorkItem> OnCompletion() override;
AuSPtr<AuAsync::IWorkItem> OnSingleCompletion() override; AuSPtr<AuAsync::IWorkItem> OnSingleCompletion() override;
AuSPtr<AuAsync::IWorkItem> OnSingleCompletionIntl();
void TryCreateInternal();
void TryCollectInternal();
bool WaitForAnyMS(AuUInt32 uTimeoutOrZeroMS) override; bool WaitForAnyMS(AuUInt32 uTimeoutOrZeroMS) override;
bool WaitForAllMS(AuUInt32 uTimeoutOrZeroMS) override; bool WaitForAllMS(AuUInt32 uTimeoutOrZeroMS) override;
@ -50,6 +53,8 @@ namespace Aurora::IO::CompletionGroup
void ResetAnd(); void ResetAnd();
void MakeInternalAsync(AuWorkerID pid);
private: private:
AuMutex mutex; AuMutex mutex;
AuCriticalSection cs; AuCriticalSection cs;
@ -59,6 +64,8 @@ namespace Aurora::IO::CompletionGroup
AuSPtr<ICompletionGroupHooks> pCallbacks; AuSPtr<ICompletionGroupHooks> pCallbacks;
AuSPtr<AuAsync::IWorkItem> pAnyBarrier; AuSPtr<AuAsync::IWorkItem> pAnyBarrier;
AuSPtr<AuAsync::IWorkItem> pAndBarrier; AuSPtr<AuAsync::IWorkItem> pAndBarrier;
AuSPtr<AuAsync::IWorkItem> pAnyBarrierInternal;
AuWorkerID workerId;
AuList<AuPair<AuSPtr<IIOProcessorManualInvoker>, bool>> callbackTicks; AuList<AuPair<AuSPtr<IIOProcessorManualInvoker>, bool>> callbackTicks;
AuUInt32 uAdded {}; AuUInt32 uAdded {};
AuUInt32 uTriggered {}; AuUInt32 uTriggered {};