Somewhat fixed thread pool

This commit is contained in:
Dynamitos
2021-12-15 00:05:42 +01:00
parent f4ce5f9585
commit 8ccaa26223
8 changed files with 353 additions and 185 deletions
+88 -76
View File
@@ -3,19 +3,20 @@
using namespace Seele;
Event::Event()
: flag(new std::atomic_bool())
{}
: flag(new std::atomic_bool())
{
}
Event::Event(nullptr_t)
: flag(nullptr)
{}
{
}
Event::Event(const std::string& name)
: name(name)
, flag(new std::atomic_bool())
{}
Event::Event(const std::string &name)
: name(name), flag(new std::atomic_bool())
{
}
void Event::raise()
{
@@ -23,7 +24,7 @@ void Event::raise()
getGlobalThreadPool().notify(*this);
}
void Event::reset()
{
{
flag->store(0);
}
@@ -36,7 +37,7 @@ ThreadPool::ThreadPool(uint32 threadCount)
: workers(threadCount)
{
running.store(true);
for(uint32 i = 0; i < threadCount; ++i)
for (uint32 i = 0; i < threadCount; ++i)
{
workers[i] = std::thread(&ThreadPool::threadLoop, this, false);
}
@@ -45,48 +46,52 @@ ThreadPool::ThreadPool(uint32 threadCount)
ThreadPool::~ThreadPool()
{
running.store(false);
for(auto& thread : workers)
for (auto &thread : workers)
{
thread.join();
}
}
void ThreadPool::addJob(Job&& job)
void ThreadPool::enqueueWaiting(Event &event, Promise* job)
{
std::unique_lock lock(jobQueueLock);
//std::cout << "Adding job " << job.id << std::endl;
jobQueue.add(std::move(job));
jobQueueCV.notify_one();
assert(!job->done());
if(event == nullptr)
{
std::unique_lock lock(jobQueueLock);
jobQueue.add(job);
jobQueueCV.notify_one();
}
else
{
std::unique_lock lock(waitingLock);
waitingJobs[event].add(job);
}
}
void ThreadPool::addJob(MainJob&& job)
void ThreadPool::enqueueWaiting(Event &event, MainPromise* job)
{
std::unique_lock lock(mainJobLock);
//std::cout << "Adding main job " << job.id << std::endl;
mainJobs.add(std::move(job));
mainJobCV.notify_one();
assert(!job->done());
if(event == nullptr)
{
std::unique_lock lock(mainJobLock);
mainJobs.add(job);
mainJobCV.notify_one();
}
else
{
std::unique_lock lock(waitingMainLock);
waitingMainJobs[event].add(job);
}
}
void ThreadPool::enqueueWaiting(Event& event, Job&& job)
{
//std::cout << job.id << " waiting for event " << event.name << std::endl;
std::unique_lock lock(waitingLock);
waitingJobs[event].add(std::move(job));
}
void ThreadPool::enqueueWaiting(Event& event, MainJob&& job)
{
//std::cout << job.id << " main waiting for event " << event.name << std::endl;
std::unique_lock lock(waitingMainLock);
waitingMainJobs[event].add(std::move(job));
}
void ThreadPool::notify(Event& event)
void ThreadPool::notify(Event &event)
{
{
std::unique_lock lock(jobQueueLock);
std::unique_lock lock2(waitingLock);
List<Job>& jobs = waitingJobs[event];
for(auto& job : jobs)
List<Promise*> &jobs = waitingJobs[event];
for (auto &job : jobs)
{
//assert(job.id != -1ull);
//std::cout << "Waking up job " << job.id << std::endl;
jobQueue.add(std::move(job));
jobQueue.add(job);
jobQueueCV.notify_one();
}
jobs.clear();
@@ -94,67 +99,74 @@ void ThreadPool::notify(Event& event)
{
std::unique_lock lock(mainJobLock);
std::unique_lock lock2(waitingMainLock);
List<MainJob>& jobs = waitingMainJobs[event];
for(auto& job : jobs)
List<MainPromise*> &jobs = waitingMainJobs[event];
for (auto &job : jobs)
{
//assert(job.id != -1ull);
//std::cout << "Waking up main job " << job.id << std::endl;
mainJobs.add(std::move(job));
mainJobs.add(job);
mainJobCV.notify_one();
}
jobs.clear();
}
}
void ThreadPool::tryMainJob()
void ThreadPool::threadLoop(const bool mainThread)
{
MainJob job;
while (running.load())
{
std::unique_lock lock(mainJobLock);
if(!mainJobs.empty())
if (mainThread)
{
job = std::move(mainJobs.retrieve());
MainPromise* job;
{
std::unique_lock lock(mainJobLock);
if(mainJobs.empty())
{
mainJobCV.wait(lock);
}
if (!mainJobs.empty())
{
job = mainJobs.retrieve();
}
else
{
continue;
}
}
job->resume();
if (job->done())
{
job->raise();
}
}
else
{
return;
}
}
job.resume();
}
void ThreadPool::threadLoop(const bool mainThread)
{
while(running.load())
{
if(mainThread)
{
tryMainJob();
}
Job job;
{
std::unique_lock lock(jobQueueLock);
if(jobQueue.empty())
Promise* job;
{
jobQueueCV.wait(lock);
std::unique_lock lock(jobQueueLock);
if (jobQueue.empty())
{
jobQueueCV.wait(lock);
}
if (!jobQueue.empty())
{
job = jobQueue.retrieve();
}
else
{
continue;
}
}
if(!jobQueue.empty())
//std::cout << "Starting job " << job.id << std::endl;
job->resume();
if (job->done())
{
job = std::move(jobQueue.retrieve());
job->raise();
}
else
{
continue;
}
}
//std::cout << "Starting job " << job.id << std::endl;
job.resume();
if(job.done())
{
job.raise();
}
}
}
ThreadPool& Seele::getGlobalThreadPool()
ThreadPool &Seele::getGlobalThreadPool()
{
static ThreadPool threadPool;
return threadPool;