summaryrefslogtreecommitdiff
path: root/lib/worker.cpp
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2021-01-19 20:35:29 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2021-01-19 20:35:29 +0000
commit96a58cc251354954241aa2c9008b25d98daaad92 (patch)
tree383d379fe8bbf5026a5a0cdea4a376485c65b318 /lib/worker.cpp
parentFactor to support worlds, objects, windows etc (diff)
downloadilt-96a58cc251354954241aa2c9008b25d98daaad92.tar.bz2
ilt-96a58cc251354954241aa2c9008b25d98daaad92.tar.xz
ilt-96a58cc251354954241aa2c9008b25d98daaad92.zip
Add basic work and worker thread pool
Well... that requires GCC 11 cos 10 doesn't implement semaphore.
Diffstat (limited to 'lib/worker.cpp')
-rw-r--r--lib/worker.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/worker.cpp b/lib/worker.cpp
new file mode 100644
index 0000000..3c12caa
--- /dev/null
+++ b/lib/worker.cpp
@@ -0,0 +1,46 @@
+#include "worker.h"
+#include "work.h"
+#include <algorithm>
+#include <iterator>
+#include <mutex>
+
+Worker::Worker() : todoLen {0}
+{
+ std::generate_n(std::back_inserter(threads), std::thread::hardware_concurrency(), [this]() {
+ return std::thread {&Worker::worker, this};
+ });
+}
+
+Worker::~Worker()
+{
+ todoLen.release(std::thread::hardware_concurrency());
+ std::for_each(threads.begin(), threads.end(), [](auto & th) {
+ th.join();
+ });
+}
+
+void
+Worker::addWork(WorkPtr j)
+{
+ std::lock_guard<std::mutex> lck {todoMutex};
+ todoLen.release();
+ todo.emplace_back(std::move(j));
+}
+
+void
+Worker::worker()
+{
+ auto job = [this]() {
+ todoLen.acquire();
+ std::lock_guard<std::mutex> lck {todoMutex};
+ if (todo.size()) {
+ WorkPtr x = std::move(todo.front());
+ todo.pop_front();
+ return x;
+ }
+ return WorkPtr {};
+ };
+ while (auto j = job()) {
+ j->doWork();
+ }
+}