[*] Lock access to wpWorkers (e037fc21, a7dfd899 cleanup cont) and remove a redundant write lock to solve a deadlock

This commit is contained in:
Reece Wilson 2023-11-11 12:32:16 +00:00
parent a7dfd899f8
commit 151bb106fb
3 changed files with 15 additions and 16 deletions

View File

@ -20,7 +20,8 @@ namespace Aurora::Async
AuSPtr<ThreadState> GroupState::GetThreadByIndex(ThreadId_t uIndex) AuSPtr<ThreadState> GroupState::GetThreadByIndex(ThreadId_t uIndex)
{ {
// TODO: deinit mutex {
AU_LOCK_GUARD(this->deinitMutex);
if (AuArraySize(this->wpWorkers) > uIndex) if (AuArraySize(this->wpWorkers) > uIndex)
{ {
if (auto pState = AuTryLockMemoryType(this->wpWorkers[uIndex])) if (auto pState = AuTryLockMemoryType(this->wpWorkers[uIndex]))
@ -28,6 +29,7 @@ namespace Aurora::Async
return pState; return pState;
} }
} }
}
AU_LOCK_GUARD(this->workersMutex); AU_LOCK_GUARD(this->workersMutex);
@ -41,10 +43,13 @@ namespace Aurora::Async
void GroupState::Decommit(ThreadId_t id) void GroupState::Decommit(ThreadId_t id)
{ {
{
AU_LOCK_GUARD(this->deinitMutex);
if (AuArraySize(this->wpWorkers) > id) if (AuArraySize(this->wpWorkers) > id)
{ {
this->wpWorkers[id] = {}; this->wpWorkers[id] = {};
} }
}
AU_LOCK_GUARD(this->workersMutex); AU_LOCK_GUARD(this->workersMutex);

View File

@ -25,6 +25,7 @@ namespace Aurora::Async
// tracked workers // tracked workers
AuThreadPrimitives::Mutex workersMutex; AuThreadPrimitives::Mutex workersMutex;
AuFutexMutex deinitMutex;
AuBST<ThreadId_t, AuSPtr<ThreadState>> workers; AuBST<ThreadId_t, AuSPtr<ThreadState>> workers;
AuWPtr<ThreadState> wpWorkers[32]; // linear non-locking lookup table AuWPtr<ThreadState> wpWorkers[32]; // linear non-locking lookup table
// //

View File

@ -176,7 +176,6 @@ namespace Aurora::Async
size_t ThreadPool::GetThreadWorkersCount(ThreadGroup_t group) size_t ThreadPool::GetThreadWorkersCount(ThreadGroup_t group)
{ {
AU_LOCK_GUARD(this->pRWReadView);
return GetGroup(group)->workers.size(); return GetGroup(group)->workers.size();
} }
@ -706,8 +705,6 @@ namespace Aurora::Async
AuBST<ThreadGroup_t, AuList<ThreadId_t>> ThreadPool::GetThreads() AuBST<ThreadGroup_t, AuList<ThreadId_t>> ThreadPool::GetThreads()
{ {
AU_LOCK_GUARD(this->pRWReadView);
AuBST<ThreadGroup_t, AuList<ThreadId_t>> ret; AuBST<ThreadGroup_t, AuList<ThreadId_t>> ret;
for (auto pGroup : this->threadGroups_) for (auto pGroup : this->threadGroups_)
@ -719,6 +716,7 @@ namespace Aurora::Async
continue; continue;
} }
AU_LOCK_GUARD(pGroup->workersMutex);
AuTryReserve(workers, pGroup->workers.size()); AuTryReserve(workers, pGroup->workers.size());
for (const auto &thread : pGroup->workers) for (const auto &thread : pGroup->workers)
@ -764,11 +762,10 @@ namespace Aurora::Async
void ThreadPool::Signal(WorkerId_t workerId) void ThreadPool::Signal(WorkerId_t workerId)
{ {
AU_LOCK_GUARD(this->pRWReadView);
auto group = GetGroup(workerId.first); auto group = GetGroup(workerId.first);
if (workerId.second == Async::kThreadIdAny) if (workerId.second == Async::kThreadIdAny)
{ {
AU_LOCK_GUARD(group->workersMutex);
for (auto &jobWorker : group->workers) for (auto &jobWorker : group->workers)
{ {
jobWorker.second->running->Set(); jobWorker.second->running->Set();
@ -782,8 +779,6 @@ namespace Aurora::Async
AuSPtr<AuLoop::ILoopSource> ThreadPool::WorkerToLoopSource(WorkerId_t workerId) AuSPtr<AuLoop::ILoopSource> ThreadPool::WorkerToLoopSource(WorkerId_t workerId)
{ {
AU_LOCK_GUARD(this->pRWReadView);
auto a = GetThreadHandle(workerId); auto a = GetThreadHandle(workerId);
if (!a) if (!a)
{ {
@ -1288,7 +1283,6 @@ namespace Aurora::Async
} }
{ {
AU_LOCK_GUARD(this->rwlock_->AsWritable());
state->Decommit(id.second); state->Decommit(id.second);
} }
} }
@ -1361,8 +1355,6 @@ namespace Aurora::Async
AuList<AuSPtr<ThreadState>> ThreadPool::GetThreadHandles(WorkerId_t id) AuList<AuSPtr<ThreadState>> ThreadPool::GetThreadHandles(WorkerId_t id)
{ {
AU_LOCK_GUARD(this->pRWReadView);
auto group = GetGroup(id.first); auto group = GetGroup(id.first);
if (!group) if (!group)
{ {
@ -1379,6 +1371,7 @@ namespace Aurora::Async
} }
else else
{ {
AU_LOCK_GUARD(group->workersMutex);
for (const auto &[key, value] : group->workers) for (const auto &[key, value] : group->workers)
{ {
ret.push_back(value); ret.push_back(value);