summaryrefslogtreecommitdiff
path: root/src/buildtool/multithreading/task_system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildtool/multithreading/task_system.cpp')
-rw-r--r--src/buildtool/multithreading/task_system.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/buildtool/multithreading/task_system.cpp b/src/buildtool/multithreading/task_system.cpp
index ee5be910..bde1ef2c 100644
--- a/src/buildtool/multithreading/task_system.cpp
+++ b/src/buildtool/multithreading/task_system.cpp
@@ -17,15 +17,24 @@ TaskSystem::TaskSystem(std::size_t number_of_threads)
}
TaskSystem::~TaskSystem() {
- Finish();
- for (auto& q : queues_) {
- q.done();
- }
+ Finish(); // wait for tasks to finish
+ Shutdown(); // stop the threads
for (auto& t : threads_) {
t.join();
}
}
+void TaskSystem::Shutdown() noexcept {
+ shutdown_ = true;
+ // Abort the workload counter in case a system shut down was requested while
+ // the task queues (workload) are not yet empty and someone is still waiting
+ // on this counter to become zero.
+ total_workload_.Abort();
+ for (auto& q : queues_) {
+ q.done();
+ }
+}
+
void TaskSystem::Finish() noexcept {
// When starting a new task system all spawned threads will immediately go
// to sleep and wait for tasks. Even after adding some tasks, it can take a
@@ -38,7 +47,7 @@ void TaskSystem::Finish() noexcept {
void TaskSystem::Run(std::size_t idx) {
gsl_Expects(thread_count_ > 0);
- while (true) {
+ while (not shutdown_) {
std::optional<Task> t{};
for (std::size_t i = 0; i < thread_count_; ++i) {
t = queues_[(idx + i) % thread_count_].try_pop();
@@ -50,7 +59,7 @@ void TaskSystem::Run(std::size_t idx) {
// NOLINTNEXTLINE(clang-analyzer-core.DivideZero)
t = t ? t : queues_[idx % thread_count_].pop();
- if (!t) {
+ if (not t or shutdown_) {
break;
}