[*] AuAsync optimization: remove some rwlock guards

This commit is contained in:
Reece Wilson 2023-08-10 01:31:10 +01:00
parent 7dda7ae358
commit a0c82788d9
2 changed files with 47 additions and 46 deletions

View File

@ -619,9 +619,14 @@ namespace Aurora::Async
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
for (auto &[groupId, group] : this->threads_)
for (auto pGroup : this->threadGroups_)
{
for (auto &[id, worker] : group->workers)
if (!pGroup)
{
continue;
}
for (auto &[id, worker] : pGroup->workers)
{
if (trySelfPid == worker->id)
{
@ -660,9 +665,14 @@ namespace Aurora::Async
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
for (auto &[groupId, group] : this->threads_)
for (auto pGroup : this->threadGroups_)
{
for (auto &[id, pState] : group->workers)
if (!pGroup)
{
continue;
}
for (auto &[id, pState] : pGroup->workers)
{
// main loop:
if (pState && pState->cvWorkMutex && pState->cvVariable)
@ -676,7 +686,7 @@ namespace Aurora::Async
}
// thread object:
if (!group->IsSysThread()) // bug?
if (!pGroup->IsSysThread()) // bug?
{
pState->threadObject->SendExitSignal();
threads.push_back(pState->threadObject);
@ -799,18 +809,23 @@ namespace Aurora::Async
AuBST<ThreadGroup_t, AuList<ThreadId_t>> ret;
for (const auto &group : this->threads_)
for (auto pGroup : this->threadGroups_)
{
AuList<ThreadId_t> workers;
AuTryReserve(workers, group.second->workers.size());
if (!pGroup)
{
continue;
}
for (const auto &thread : group.second->workers)
AuTryReserve(workers, pGroup->workers.size());
for (const auto &thread : pGroup->workers)
{
workers.push_back(thread.second->id.second);
}
ret[group.first] = workers;
ret[pGroup->group] = workers;
}
return ret;
@ -881,9 +896,14 @@ namespace Aurora::Async
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
for (const auto &re : this->threads_)
for (auto pGroup : this->threadGroups_)
{
for (auto &jobWorker : re.second->workers)
if (!pGroup)
{
continue;
}
for (auto &jobWorker : pGroup->workers)
{
SysAssert(Barrier(jobWorker.second->id, 0, false, false));
}
@ -1035,29 +1055,21 @@ namespace Aurora::Async
gCurrentPool = AuSharedFromThis();
}
AuSPtr<GroupState> group;
AuSPtr<GroupState> pGroup;
// Try fetch or allocate group
{
AuSPtr<GroupState>* groupPtr;
if (!AuTryFind(this->threads_, workerId.first, groupPtr))
if (!(pGroup = threadGroups_[workerId.first]))
{
group = AuMakeShared<GroupState>();
pGroup = AuMakeShared<GroupState>();
if (!group->Init())
if (!pGroup->Init())
{
SysPushErrorMemory("Not enough memory to intiialize a new group state");
return false;
}
if (!AuTryInsert(this->threads_, AuMakePair(workerId.first, group)))
{
return false;
}
}
else
{
group = *groupPtr;
this->threadGroups_[workerId.first] = pGroup;
}
}
@ -1065,7 +1077,7 @@ namespace Aurora::Async
{
AuSPtr<ThreadState>* ret;
if (AuTryFind(group->workers, workerId.second, ret))
if (AuTryFind(pGroup->workers, workerId.second, ret))
{
SysPushErrorGeneric("Thread ID already exists");
return false;
@ -1079,7 +1091,7 @@ namespace Aurora::Async
return {};
}
threadState->parent = group;
threadState->parent = pGroup;
threadState->id = workerId;
threadState->asyncLoop = AuMakeShared<AsyncLoop>();
if (!threadState->asyncLoop)
@ -1153,7 +1165,7 @@ namespace Aurora::Async
tlsWorkerId = WorkerPId_t(AuSharedFromThis(), workerId);
}
group->AddWorker(workerId.second, threadState);
pGroup->AddWorker(workerId.second, threadState);
return true;
}
@ -1371,19 +1383,11 @@ namespace Aurora::Async
AuSPtr<GroupState> ThreadPool::GetGroup(ThreadGroup_t type)
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
AuSPtr<GroupState>* ret;
if (!AuTryFind(this->threads_, type, ret))
{
return {};
}
return *ret;
return this->threadGroups_[type];
}
AuSPtr<ThreadState> ThreadPool::GetThreadState()
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
auto thread = gCurrentPool.lock();
if (!thread)
{
@ -1411,8 +1415,6 @@ namespace Aurora::Async
AuSPtr<ThreadState> ThreadPool::GetThreadStateNoWarn()
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
auto thread = gCurrentPool.lock();
if (!thread)
{
@ -1437,8 +1439,6 @@ namespace Aurora::Async
AuSPtr<ThreadState> ThreadPool::GetThreadHandle(WorkerId_t id)
{
AU_LOCK_GUARD(this->rwlock_->AsReadable());
auto group = GetGroup(id.first);
if (!group)
{
@ -1497,12 +1497,15 @@ namespace Aurora::Async
if (uNow == 0)
{
for (const auto &[group, pState] : this->pPool->threads_)
for (const auto &pState : this->pPool->threadGroups_)
{
if (pState)
{
pState->BroadCast();
}
}
}
}
AuSPtr<AuAsync::ThreadPool> pPool;
};

View File

@ -135,9 +135,7 @@ namespace Aurora::Async
AuSPtr<ThreadState> GetThreadHandle(WorkerId_t id);
AuList<AuSPtr<ThreadState>> GetThreadHandles(WorkerId_t id);
using ThreadDb_t = AuBST<ThreadGroup_t, AuSPtr<GroupState>>;
ThreadDb_t threads_;
AuSPtr<GroupState> threadGroups_[255];
AuUInt32 shuttingdown_ {};
bool shutdown {};
AuThreadPrimitives::RWRenterableLock rwlock_;