[*] 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

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

View File

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

View File

@ -7,6 +7,7 @@
***/
#include <Source/RuntimeInternal.hpp>
#include "AuThreadStateSingletons.hpp"
#include <Source/IO/CompletionGroup/CompletionGroup.hpp>
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)
{
@ -44,7 +45,16 @@ namespace Aurora::Async
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::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::Net::INetInterface> GetIONetInterface(AuWorkerPId_t pid);
AuSPtr<AuIO::Net::INetWorker> GetIONetWorker(AuWorkerPId_t pid);

View File

@ -801,11 +801,11 @@ namespace Aurora::Async
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 {};
@ -815,27 +815,27 @@ namespace Aurora::Async
{
if (auto pState = this->GetThreadHandle(id))
{
return pState->singletons.GetIOGroup();
return pState->singletons.GetIOGroup({ this->SharedFromThis(), id });
}
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 {};
}
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 {};
@ -1418,6 +1418,8 @@ namespace Aurora::Async
{
state->Decommit(id.second);
}
pLocalState->Deinit();
}
AuSPtr<GroupState> ThreadPool::GetGroup(ThreadGroup_t type)

View File

@ -186,6 +186,8 @@ namespace Aurora::IO::CompletionGroup
// anyone else?
this->ResetMemoryPins();
}
this->TryCollectInternal();
}
void CompletionGroup::AddWorkItem(const AuSPtr<ICompletionGroupWorkItem> &pCompletable)
@ -194,6 +196,7 @@ namespace Aurora::IO::CompletionGroup
AU_LOCK_GUARD(this->mutex);
this->workItems.push_back(pCompletable);
AuAtomicAdd(&this->uAdded, 1u);
this->TryCreateInternal();
}
void CompletionGroup::UnsafeRemoveItem(const AuSPtr<ICompletionGroupWorkItem> &pCompletable)
@ -335,15 +338,8 @@ namespace Aurora::IO::CompletionGroup
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)
{
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;
}
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()
{
return AuMakeShared<CompletionGroup>();

View File

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