Files
Seele/src/Engine/ThreadPool.cpp
T

146 lines
3.3 KiB
C++
Raw Normal View History

2021-10-12 14:20:30 +02:00
#include "ThreadPool.h"
using namespace Seele;
2021-11-01 20:25:16 +01:00
Event::Event()
: flag(new std::atomic_bool())
{}
2021-10-23 00:22:35 +02:00
2021-11-01 20:25:16 +01:00
Event::Event(const std::string& name)
: name(name)
, flag(new std::atomic_bool())
{}
void Event::raise()
2021-10-23 00:22:35 +02:00
{
2021-11-01 20:25:16 +01:00
flag->store(1);
getGlobalThreadPool().notify(this);
}
void Event::reset()
{
flag->store(0);
2021-10-23 00:22:35 +02:00
}
2021-10-12 14:20:30 +02:00
2021-11-01 20:25:16 +01:00
bool Event::await_ready()
{
return flag->load();
2021-10-12 14:20:30 +02:00
}
ThreadPool::ThreadPool(uint32 threadCount)
: workers(threadCount)
{
2021-11-01 20:25:16 +01:00
running.store(true);
for(uint32 i = 0; i < threadCount; ++i)
{
workers[i] = std::thread(&ThreadPool::threadLoop, this, i == 0);
}
2021-10-12 14:20:30 +02:00
}
2021-10-23 00:22:35 +02:00
ThreadPool::~ThreadPool()
2021-10-12 14:20:30 +02:00
{
running.store(false);
2021-10-23 00:22:35 +02:00
for(auto& thread : workers)
{
thread.join();
}
}
2021-11-01 20:25:16 +01:00
void ThreadPool::addJob(Job&& job)
{
std::unique_lock lock(jobQueueLock);
2021-11-19 15:08:56 +01:00
std::cout << "Adding job " << job.id << std::endl;
2021-11-11 20:12:50 +01:00
jobQueue.add(std::move(job));
jobQueueCV.notify_one();
2021-11-01 20:25:16 +01:00
}
void ThreadPool::addJob(MainJob&& job)
{
std::unique_lock lock(mainJobLock);
2021-11-19 15:08:56 +01:00
std::cout << "Adding main job " << job.id << std::endl;
2021-11-11 20:12:50 +01:00
mainJobs.add(std::move(job));
mainJobCV.notify_one();
2021-11-01 20:25:16 +01:00
}
void ThreadPool::enqueueWaiting(Event* event, Job&& job)
{
2021-11-19 15:08:56 +01:00
std::cout << job.id << " waiting for event " << event->name << std::endl;
2021-11-01 20:25:16 +01:00
std::unique_lock lock(waitingLock);
2021-11-11 20:12:50 +01:00
waitingJobs[*event].add(std::move(job));
2021-11-01 20:25:16 +01:00
}
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job)
{
2021-11-19 15:08:56 +01:00
std::cout << job.id << " main waiting for event " << event->name << std::endl;
2021-11-01 20:25:16 +01:00
std::unique_lock lock(waitingMainLock);
2021-11-11 20:12:50 +01:00
waitingMainJobs[*event].add(std::move(job));
2021-11-01 20:25:16 +01:00
}
void ThreadPool::notify(Event* event)
{
{
std::unique_lock lock(jobQueueLock);
std::unique_lock lock2(waitingLock);
while(!waitingJobs[*event].empty())
2021-11-01 20:25:16 +01:00
{
2021-11-19 15:08:56 +01:00
std::cout << "Waking up job " << waitingJobs[*event].front().id << std::endl;
Job job = std::move(waitingJobs[*event].retrieve());
jobQueue.add(std::move(job));
2021-11-11 20:12:50 +01:00
jobQueueCV.notify_one();
2021-11-01 20:25:16 +01:00
}
}
{
std::unique_lock lock(mainJobLock);
std::unique_lock lock2(waitingMainLock);
2021-11-13 19:28:18 +01:00
while(!waitingMainJobs[*event].empty())
2021-11-01 20:25:16 +01:00
{
2021-11-19 15:08:56 +01:00
std::cout << "Waking up main job " << waitingMainJobs[*event].front().id << std::endl;
2021-11-13 19:28:18 +01:00
mainJobs.add(std::move(waitingMainJobs[*event].retrieve()));
2021-11-11 20:12:50 +01:00
mainJobCV.notify_one();
2021-11-01 20:25:16 +01:00
}
}
}
2021-11-19 15:08:56 +01:00
void ThreadPool::tryMainJob()
{
MainJob job;
{
std::unique_lock lock(mainJobLock);
if(!mainJobs.empty())
{
job = std::move(mainJobs.retrieve());
}
else
{
return;
}
}
job.resume();
}
2021-11-01 20:25:16 +01:00
void ThreadPool::threadLoop(const bool mainThread)
{
while(running.load())
{
if(mainThread)
{
2021-11-19 15:08:56 +01:00
tryMainJob();
}
Job job;
{
std::unique_lock lock(jobQueueLock);
if(jobQueue.empty())
2021-11-01 20:25:16 +01:00
{
2021-11-19 15:08:56 +01:00
jobQueueCV.wait(lock);
}
if(!jobQueue.empty())
{
job = std::move(jobQueue.retrieve());
}
else
{
continue;
2021-11-01 20:25:16 +01:00
}
}
2021-11-19 15:08:56 +01:00
std::cout << "Starting job " << job.id << std::endl;
job.resume();
2021-11-01 20:25:16 +01:00
}
}
2021-10-23 00:22:35 +02:00
ThreadPool& Seele::getGlobalThreadPool()
{
static ThreadPool threadPool;
return threadPool;
2021-10-12 14:20:30 +02:00
}