AuroraRuntime/Source/Async/AuGroupWorkQueue.cpp

109 lines
2.7 KiB
C++

/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuGroupWorkQueue.cpp
Date: 2023-11-04
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "AuGroupWorkQueue.hpp"
#include "Async.hpp"
#include "ThreadPool.hpp"
#include "IAsyncRunnable.hpp"
namespace Aurora::Async
{
void GroupWorkQueue::AddWorkEntry(WorkEntry_t entry)
{
AU_DEBUG_MEMCRUNCH;
auto prio = (int)entry.second->GetPrio();
SysAssert(prio < AuAsync::kEWorkPriorityCount, "Invalid PRIO");
AU_LOCK_GUARD(this->mutex);
this->sortedWork[prio].push_back(entry);
}
bool GroupWorkQueue::IsEmpty()
{
AU_LOCK_GUARD(this->mutex);
for (AU_ITERATE_N(i, AuAsync::kEWorkPriorityCount))
{
if (this->sortedWork[i].size())
{
return false;
}
}
return true;
}
bool GroupWorkQueue::IsEmpty(ThreadPool *pPool, AuWorkerId_t id)
{
#if 1
auto pHandle = pPool->GetThreadHandle(id);
if (!pHandle)
{
return false;
}
return !AuAtomicLoad(&pHandle->sync.cvHasWork);
#else
AU_LOCK_GUARD(this->mutex);
for (AU_ITERATE_N(i, AuAsync::kEWorkPriorityCount))
{
for (const auto &[srcId, pA] : this->sortedWork[i])
{
if (id == srcId)
{
return false;
}
}
}
return true;
#endif
}
void GroupWorkQueue::Dequeue(AuList<WorkEntry_t> &queue,
AuUInt uMaxPopCount,
AuAsync::ThreadId_t id)
{
AU_LOCK_GUARD(this->mutex);
AuUInt uAnyCount {};
for (AU_ITERATE_N(i, AuAsync::kEWorkPriorityCount))
{
auto &group = this->sortedWork[(int)AuAsync::kEWorkPriorityMaxLegal - i];
for (auto itr = group.begin(); ((itr != group.end()) && (queue.size() < uMaxPopCount)); )
{
if ((!uAnyCount) &&
(itr->first == Async::kThreadIdAny))
{
queue.push_back(*itr);
itr = group.erase(itr);
uAnyCount++;
continue;
}
if ((itr->first != Async::kThreadIdAny) &&
(itr->first == id))
{
queue.push_back(*itr);
itr = group.erase(itr);
continue;
}
itr++;
}
if (queue.size())
{
break;
}
}
}
}