2021-10-12 14:20:30 +02:00
|
|
|
#include "ThreadPool.h"
|
2024-07-05 12:02:46 +02:00
|
|
|
#include "MinimalEngine.h"
|
2021-10-12 14:20:30 +02:00
|
|
|
|
|
|
|
|
using namespace Seele;
|
|
|
|
|
|
2024-07-05 12:02:46 +02:00
|
|
|
Globals globals;
|
|
|
|
|
|
|
|
|
|
Globals& Seele::getGlobals() { return globals; }
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
ThreadPool::ThreadPool(uint32 numWorkers) {
|
|
|
|
|
for (uint32 i = 0; i < numWorkers; ++i) {
|
2023-12-17 16:16:46 +01:00
|
|
|
workers.add(std::thread(&ThreadPool::work, this));
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
2021-10-12 14:20:30 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
ThreadPool::~ThreadPool() {
|
2022-03-26 12:55:04 +01:00
|
|
|
{
|
2024-07-18 11:45:56 +02:00
|
|
|
std::unique_lock l(queueLock);
|
2023-12-17 16:16:46 +01:00
|
|
|
running = false;
|
2024-07-18 11:45:56 +02:00
|
|
|
queueCV.notify_all();
|
2022-03-26 12:55:04 +01:00
|
|
|
}
|
2024-06-09 12:20:04 +02:00
|
|
|
for (auto& worker : workers) {
|
2022-03-26 12:55:04 +01:00
|
|
|
worker.join();
|
|
|
|
|
}
|
2022-02-14 16:29:26 +01:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void ThreadPool::runAndWait(List<std::function<void()>> functions) {
|
2024-05-23 14:58:14 +02:00
|
|
|
std::unique_lock l(taskLock);
|
2024-07-18 11:45:56 +02:00
|
|
|
auto newTask = runningTasks.add();
|
|
|
|
|
newTask->numRemaining = functions.size();
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock q(queueLock);
|
|
|
|
|
while (!functions.empty()) {
|
|
|
|
|
queue.add(QueueEntry{
|
|
|
|
|
.func = std::move(functions.back()),
|
|
|
|
|
.task = &*newTask,
|
|
|
|
|
});
|
|
|
|
|
functions.popBack();
|
|
|
|
|
}
|
|
|
|
|
queueCV.notify_all();
|
|
|
|
|
}
|
|
|
|
|
while (newTask->numRemaining > 0) {
|
2024-05-23 14:58:14 +02:00
|
|
|
completedCV.wait(l);
|
|
|
|
|
}
|
2024-07-18 11:45:56 +02:00
|
|
|
runningTasks.remove(newTask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ThreadPool::runAsync(std::function<void()> func) {
|
|
|
|
|
std::unique_lock l(queueLock);
|
|
|
|
|
queue.add(QueueEntry{
|
|
|
|
|
.func = std::move(func),
|
|
|
|
|
.task = nullptr,
|
|
|
|
|
});
|
|
|
|
|
queueCV.notify_one();
|
2024-05-23 14:58:14 +02:00
|
|
|
}
|
2022-03-19 22:45:30 +01:00
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void ThreadPool::work() {
|
|
|
|
|
while (running) {
|
2024-07-18 11:45:56 +02:00
|
|
|
std::unique_lock l(queueLock);
|
|
|
|
|
while (queue.empty()) {
|
|
|
|
|
queueCV.wait(l);
|
2024-06-09 12:20:04 +02:00
|
|
|
if (!running) {
|
2023-12-17 16:16:46 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2021-11-19 15:08:56 +01:00
|
|
|
}
|
2024-07-18 11:45:56 +02:00
|
|
|
auto entry = std::move(queue.front());
|
|
|
|
|
queue.popFront();
|
2023-12-17 16:16:46 +01:00
|
|
|
l.unlock();
|
2024-07-18 11:45:56 +02:00
|
|
|
entry.func();
|
2023-12-17 16:16:46 +01:00
|
|
|
l.lock();
|
2024-07-18 11:45:56 +02:00
|
|
|
if (entry.task != nullptr) {
|
|
|
|
|
std::unique_lock t(taskLock);
|
|
|
|
|
entry.task->numRemaining--;
|
|
|
|
|
if (entry.task->numRemaining == 0) {
|
|
|
|
|
completedCV.notify_one();
|
|
|
|
|
}
|
2021-11-24 12:10:23 +01:00
|
|
|
}
|
2021-11-01 20:25:16 +01:00
|
|
|
}
|
|
|
|
|
}
|
2024-05-01 19:05:48 +02:00
|
|
|
|
|
|
|
|
static ThreadPool threadPool;
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
ThreadPool& Seele::getThreadPool() { return threadPool; }
|