116 lines
2.9 KiB
C++
116 lines
2.9 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
|
|
}
|
|
|
|
bool GroupWorkQueue::Dequeue(AuListOfHeap<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))
|
|
{
|
|
if (!AuTryInsert(queue, *itr))
|
|
{
|
|
return false;
|
|
}
|
|
itr = group.erase(itr);
|
|
uAnyCount++;
|
|
continue;
|
|
}
|
|
|
|
if ((itr->first != Async::kThreadIdAny) &&
|
|
(itr->first == id))
|
|
{
|
|
if (!AuTryInsert(queue, *itr))
|
|
{
|
|
return false;
|
|
}
|
|
itr = group.erase(itr);
|
|
continue;
|
|
}
|
|
|
|
itr++;
|
|
}
|
|
|
|
if (queue.size())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
} |