70 lines
1.3 KiB
C++
70 lines
1.3 KiB
C++
|
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||
|
//SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
|
||
|
#include "manager.h"
|
||
|
|
||
|
TM::Manager::Manager ():
|
||
|
terminating(false),
|
||
|
threads(),
|
||
|
queue(),
|
||
|
mtx(),
|
||
|
cond()
|
||
|
{}
|
||
|
|
||
|
TM::Manager::~Manager () {
|
||
|
std::unique_lock lock(mtx);
|
||
|
if (threads.empty())
|
||
|
return;
|
||
|
|
||
|
lock.unlock();
|
||
|
stop();
|
||
|
}
|
||
|
|
||
|
void TM::Manager::start () {
|
||
|
std::lock_guard lock(mtx);
|
||
|
|
||
|
std::size_t amount = std::thread::hardware_concurrency();
|
||
|
for (std::size_t i = 0; i < amount; ++i)
|
||
|
threads.emplace_back(std::thread(&Manager::loop, this));
|
||
|
}
|
||
|
|
||
|
void TM::Manager::stop () {
|
||
|
std::unique_lock lock(mtx);
|
||
|
|
||
|
terminating = true;
|
||
|
|
||
|
lock.unlock();
|
||
|
cond.notify_all();
|
||
|
for (std::thread& thread : threads)
|
||
|
thread.join();
|
||
|
|
||
|
lock.lock();
|
||
|
threads.clear();
|
||
|
terminating = false;
|
||
|
}
|
||
|
|
||
|
void TM::Manager::loop () {
|
||
|
while (true) {
|
||
|
std::unique_lock lock(mtx);
|
||
|
while (!terminating && queue.empty())
|
||
|
cond.wait(lock);
|
||
|
|
||
|
if (terminating)
|
||
|
return;
|
||
|
|
||
|
std::unique_ptr<Job> job = std::move(queue.front());
|
||
|
queue.pop();
|
||
|
lock.unlock();
|
||
|
|
||
|
job->execute();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TM::Manager::schedule (std::unique_ptr<Job> job) {
|
||
|
std::unique_lock lock(mtx);
|
||
|
queue.emplace(std::move(job));
|
||
|
|
||
|
lock.unlock();
|
||
|
cond.notify_one();
|
||
|
}
|