2021-10-12 14:20:30 +02:00
|
|
|
#include "ThreadPool.h"
|
2021-12-02 13:00:03 +01:00
|
|
|
#include <memory_resource>
|
2021-10-12 14:20:30 +02:00
|
|
|
|
|
|
|
|
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-12-02 13:00:03 +01:00
|
|
|
Event::Event(nullptr_t)
|
|
|
|
|
: flag(nullptr)
|
|
|
|
|
{}
|
|
|
|
|
|
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);
|
2021-11-24 12:10:23 +01:00
|
|
|
getGlobalThreadPool().notify(*this);
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
{
|
2021-12-02 13:00:03 +01:00
|
|
|
workers[i] = std::thread(&ThreadPool::threadLoop, this, false);
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
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
|
|
|
{
|
2021-11-14 20:36:53 +01: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-24 12:10:23 +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-24 12:10:23 +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
|
|
|
}
|
2021-12-02 13:00:03 +01:00
|
|
|
void ThreadPool::enqueueWaiting(Event& event, Job&& job)
|
2021-11-01 20:25:16 +01:00
|
|
|
{
|
2021-11-24 12:10:23 +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-24 12:10:23 +01:00
|
|
|
waitingJobs[event].add(std::move(job));
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
2021-12-02 13:00:03 +01:00
|
|
|
void ThreadPool::enqueueWaiting(Event& event, MainJob&& job)
|
2021-11-01 20:25:16 +01:00
|
|
|
{
|
2021-11-24 12:10:23 +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-24 12:10:23 +01:00
|
|
|
waitingMainJobs[event].add(std::move(job));
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
2021-11-24 12:10:23 +01:00
|
|
|
void ThreadPool::notify(Event& event)
|
2021-11-01 20:25:16 +01:00
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock lock(jobQueueLock);
|
|
|
|
|
std::unique_lock lock2(waitingLock);
|
2021-11-24 12:10:23 +01:00
|
|
|
List<Job>& jobs = waitingJobs[event];
|
|
|
|
|
for(auto& job : jobs)
|
2021-11-01 20:25:16 +01:00
|
|
|
{
|
2021-11-24 12:10:23 +01:00
|
|
|
//assert(job.id != -1ull);
|
|
|
|
|
//std::cout << "Waking up job " << job.id << std::endl;
|
2021-11-19 15:08:56 +01:00
|
|
|
jobQueue.add(std::move(job));
|
2021-11-11 20:12:50 +01:00
|
|
|
jobQueueCV.notify_one();
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
2021-11-24 12:10:23 +01:00
|
|
|
jobs.clear();
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock lock(mainJobLock);
|
|
|
|
|
std::unique_lock lock2(waitingMainLock);
|
2021-11-24 12:10:23 +01:00
|
|
|
List<MainJob>& jobs = waitingMainJobs[event];
|
|
|
|
|
for(auto& job : jobs)
|
2021-11-01 20:25:16 +01:00
|
|
|
{
|
2021-11-24 12:10:23 +01:00
|
|
|
//assert(job.id != -1ull);
|
|
|
|
|
//std::cout << "Waking up main job " << job.id << std::endl;
|
|
|
|
|
mainJobs.add(std::move(job));
|
2021-11-11 20:12:50 +01:00
|
|
|
mainJobCV.notify_one();
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
2021-11-24 12:10:23 +01:00
|
|
|
jobs.clear();
|
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-24 12:10:23 +01:00
|
|
|
//std::cout << "Starting job " << job.id << std::endl;
|
2021-11-19 15:08:56 +01:00
|
|
|
job.resume();
|
2021-11-24 12:10:23 +01:00
|
|
|
if(job.done())
|
|
|
|
|
{
|
2021-12-02 13:00:03 +01:00
|
|
|
job.raise();
|
2021-11-24 12:10:23 +01:00
|
|
|
}
|
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
|
|
|
}
|