use standard c++ threading
parent
64cf6d2096
commit
83dd8f91a7
42
main.cc
42
main.cc
|
@ -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)) {
|
||||||
|
|
78
tpool.hh
78
tpool.hh
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue