use standard c++ threading

master
Daniel Kolesa 2017-01-24 00:32:16 +01:00
parent 64cf6d2096
commit 83dd8f91a7
2 changed files with 59 additions and 61 deletions

42
main.cc
View File

@ -1,16 +1,19 @@
#include <utility>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <ostd/types.hh> #include <ostd/types.hh>
#include <ostd/vector.hh>
#include <ostd/functional.hh> #include <ostd/functional.hh>
#include <ostd/string.hh> #include <ostd/string.hh>
#include <ostd/vector.hh>
#include <ostd/map.hh> #include <ostd/map.hh>
#include <ostd/atomic.hh>
#include <ostd/filesystem.hh> #include <ostd/filesystem.hh>
#include <ostd/io.hh> #include <ostd/io.hh>
#include <ostd/platform.hh> #include <ostd/platform.hh>
#include <ostd/utility.hh> #include <ostd/utility.hh>
#include <ostd/environ.hh> #include <ostd/environ.hh>
#include <ostd/mutex.hh>
#include <ostd/condition.hh>
#include <cubescript/cubescript.hh> #include <cubescript/cubescript.hh>
@ -21,9 +24,6 @@ using ostd::Vector;
using ostd::Map; using ostd::Map;
using ostd::String; using ostd::String;
using ostd::slice_until; using ostd::slice_until;
using ostd::UniqueLock;
using ostd::Mutex;
using ostd::Condition;
using cscript::CsState; using cscript::CsState;
using cscript::CsValueRange; using cscript::CsValueRange;
@ -294,32 +294,32 @@ struct ObState: CsState {
RuleCounter(): p_cond(), p_mtx(), p_counter(0), p_result(0) {} RuleCounter(): p_cond(), p_mtx(), p_counter(0), p_result(0) {}
void wait() { void wait() {
UniqueLock<Mutex> l(p_mtx); std::unique_lock<std::mutex> l(p_mtx);
while (p_counter) { while (p_counter) {
p_cond.wait(l); p_cond.wait(l);
} }
} }
void incr() { void incr() {
UniqueLock<Mutex> l(p_mtx); std::unique_lock<std::mutex> l(p_mtx);
++p_counter; ++p_counter;
} }
void decr() { void decr() {
UniqueLock<Mutex> l(p_mtx); std::unique_lock<std::mutex> l(p_mtx);
if (!--p_counter) { if (!--p_counter) {
l.unlock(); l.unlock();
p_cond.broadcast(); p_cond.notify_all();
} }
} }
ostd::AtomicInt &get_result() { return p_result; } std::atomic_int &get_result() { return p_result; }
private: private:
Condition p_cond; std::condition_variable p_cond;
Mutex p_mtx; std::mutex p_mtx;
int p_counter; int p_counter;
ostd::AtomicInt p_result; std::atomic_int p_result;
}; };
Vector<RuleCounter *> counters; Vector<RuleCounter *> counters;
@ -409,7 +409,7 @@ struct ObState: CsState {
auto dsv = ostd::appender<String>(); auto dsv = ostd::appender<String>();
ostd::concat(dsv, subdeps); ostd::concat(dsv, subdeps);
sourcesv.set_str(ostd::move(dsv.get())); sourcesv.set_str(std::move(dsv.get()));
sourcesv.push(); sourcesv.push();
} }
@ -590,7 +590,7 @@ int main(int argc, char **argv) {
os.init_libs(); os.init_libs();
int ncpus = ostd::Thread::hardware_concurrency(); int ncpus = std::thread::hardware_concurrency();
os.new_ivar("numcpus", 4096, 1, ncpus); os.new_ivar("numcpus", 4096, 1, ncpus);
ConstCharRange fcont; ConstCharRange fcont;
@ -637,7 +637,7 @@ int main(int argc, char **argv) {
} }
os.new_ivar("numjobs", 4096, 1, jobs); os.new_ivar("numjobs", 4096, 1, jobs);
ThreadPool tpool; thread_pool tpool;
tpool.init(jobs); tpool.init(jobs);
os.register_rulecmds(); os.register_rulecmds();
@ -664,7 +664,7 @@ int main(int argc, char **argv) {
res.set_cstr(""); res.set_cstr("");
return; return;
} }
res.set_str(ostd::move( res.set_str(std::move(
ostd::env_get(args[0].get_str()).value_or(args[1].get_str()) ostd::env_get(args[0].get_str()).value_or(args[1].get_str())
)); ));
}); });
@ -696,7 +696,7 @@ int main(int argc, char **argv) {
ret += it; ret += it;
} }
} }
res.set_str(ostd::move(ret)); res.set_str(std::move(ret));
}); });
os.new_command("invoke", "s", [&os](auto &, auto args, auto &res) { os.new_command("invoke", "s", [&os](auto &, auto args, auto &res) {
@ -709,7 +709,7 @@ int main(int argc, char **argv) {
while (p.parse()) { while (p.parse()) {
ob_expand_glob(ret, p.get_item()); ob_expand_glob(ret, p.get_item());
} }
res.set_str(ostd::move(ret)); res.set_str(std::move(ret));
}); });
if ((!fcont.empty() && !os.run_bool(fcont)) || !os.run_file(deffile)) { if ((!fcont.empty() && !os.run_bool(fcont)) || !os.run_file(deffile)) {

View File

@ -1,37 +1,36 @@
#ifndef OBUILD_TPOOL_HH #ifndef OBUILD_TPOOL_HH
#define OBUILD_TPOOL_HH #define OBUILD_TPOOL_HH
#include <ostd/thread.hh> #include <utility>
#include <vector>
#include <functional>
#include <thread>
#include <mutex>
#include <condition_variable>
using ostd::Thread; struct thread_pool {
using ostd::UniqueLock; thread_pool():
using ostd::Mutex;
using ostd::Condition;
using ostd::Vector;
struct ThreadPool {
ThreadPool():
cond(), mtx(), thrs(), tasks(nullptr), last_task(nullptr), cond(), mtx(), thrs(), tasks(nullptr), last_task(nullptr),
running(false) running(false)
{} {}
~ThreadPool() { ~thread_pool() {
destroy(); destroy();
} }
static void *thr_func(void *ptr) { static void *thr_func(void *ptr) {
static_cast<ThreadPool *>(ptr)->run(); static_cast<thread_pool *>(ptr)->run();
return nullptr; return nullptr;
} }
bool init(ostd::Size size) { bool init(size_t size) {
running = true; running = true;
for (ostd::Size i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
Thread tid([this]() { run(); }); std::thread tid{[this]() { run(); }};
if (!tid) { if (!tid.joinable()) {
return false; return false;
} }
thrs.push(ostd::move(tid)); thrs.push_back(std::move(tid));
} }
return true; return true;
} }
@ -44,24 +43,23 @@ struct ThreadPool {
} }
running = false; running = false;
mtx.unlock(); mtx.unlock();
cond.broadcast(); cond.notify_all();
for (Thread &tid: thrs.iter()) { for (std::thread &tid: thrs) {
tid.join(); tid.join();
cond.broadcast(); cond.notify_all();
} }
} }
void run() { void run() {
for (;;) { for (;;) {
UniqueLock<Mutex> l(mtx); std::unique_lock<std::mutex> l(mtx);
while (running && (tasks == nullptr)) { while (running && (tasks == nullptr)) {
cond.wait(l); cond.wait(l);
} }
if (!running) { if (!running) {
l.unlock(); return;
ostd::this_thread::exit();
} }
Task *t = tasks; task *t = tasks;
tasks = t->next; tasks = t->next;
if (last_task == t) { if (last_task == t) {
last_task = nullptr; last_task = nullptr;
@ -72,9 +70,9 @@ struct ThreadPool {
} }
} }
void push(ostd::Function<void()> func) { void push(std::function<void()> func) {
mtx.lock(); mtx.lock();
Task *t = new Task(ostd::move(func)); task *t = new task(std::move(func));
if (last_task) { if (last_task) {
last_task->next = t; last_task->next = t;
} }
@ -82,27 +80,27 @@ struct ThreadPool {
if (!tasks) { if (!tasks) {
tasks = t; tasks = t;
} }
cond.signal(); cond.notify_one();
mtx.unlock(); mtx.unlock();
} }
private: private:
struct Task { struct task {
ostd::Function<void()> cb; std::function<void()> cb;
Task *next = nullptr; task *next = nullptr;
Task() = delete; task() = delete;
Task(Task const &) = delete; task(task const &) = delete;
Task(Task &&) = delete; task(task &&) = delete;
Task(ostd::Function<void()> &&cbf): cb(ostd::move(cbf)) {} task(std::function<void()> &&cbf): cb(ostd::move(cbf)) {}
Task &operator=(Task const &) = delete; task &operator=(task const &) = delete;
Task &operator=(Task &&) = delete; task &operator=(task &&) = delete;
}; };
Condition cond; std::condition_variable cond;
Mutex mtx; std::mutex mtx;
Vector<Thread> thrs; std::vector<std::thread> thrs;
Task *tasks; task *tasks;
Task *last_task; task *last_task;
bool volatile running; bool volatile running;
}; };