forked from OctaForge/OctaBuild
initial parallel build support
parent
19fb1100f8
commit
87d34dede1
81
main.cc
81
main.cc
|
@ -5,6 +5,7 @@
|
||||||
#include <ostd/types.hh>
|
#include <ostd/types.hh>
|
||||||
#include <ostd/string.hh>
|
#include <ostd/string.hh>
|
||||||
#include <ostd/vector.hh>
|
#include <ostd/vector.hh>
|
||||||
|
#include <ostd/atomic.hh>
|
||||||
|
|
||||||
#include <cubescript.hh>
|
#include <cubescript.hh>
|
||||||
|
|
||||||
|
@ -25,6 +26,55 @@ struct Rule {
|
||||||
|
|
||||||
ostd::Vector<Rule> rules;
|
ostd::Vector<Rule> rules;
|
||||||
|
|
||||||
|
struct RuleCounter;
|
||||||
|
ostd::Vector<RuleCounter *> counters;
|
||||||
|
|
||||||
|
struct RuleCounter {
|
||||||
|
RuleCounter(): cond(), mtx(), counter(0), result(0) {
|
||||||
|
counters.push(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait() {
|
||||||
|
mtx.lock();
|
||||||
|
while (counter)
|
||||||
|
cond.wait(mtx);
|
||||||
|
mtx.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void incr() {
|
||||||
|
mtx.lock();
|
||||||
|
++counter;
|
||||||
|
mtx.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void decr() {
|
||||||
|
mtx.lock();
|
||||||
|
if (!--counter) {
|
||||||
|
mtx.unlock();
|
||||||
|
cond.broadcast();
|
||||||
|
} else
|
||||||
|
mtx.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
int wait_result(int ret) {
|
||||||
|
counters.pop();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
wait();
|
||||||
|
ret = result;
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cond cond;
|
||||||
|
Mutex mtx;
|
||||||
|
volatile int counter;
|
||||||
|
ostd::AtomicInt result;
|
||||||
|
};
|
||||||
|
|
||||||
|
ThreadPool tpool;
|
||||||
|
|
||||||
/* check funcs */
|
/* check funcs */
|
||||||
|
|
||||||
static bool ob_check_ts(ostd::ConstCharRange tname,
|
static bool ob_check_ts(ostd::ConstCharRange tname,
|
||||||
|
@ -283,9 +333,14 @@ struct ObState {
|
||||||
int exec_func(ostd::ConstCharRange tname,
|
int exec_func(ostd::ConstCharRange tname,
|
||||||
const ostd::Vector<SubRule> &rlist) {
|
const ostd::Vector<SubRule> &rlist) {
|
||||||
ostd::Vector<ostd::String> subdeps;
|
ostd::Vector<ostd::String> subdeps;
|
||||||
int r = exec_list(rlist, subdeps, tname);
|
/* new scope for early destruction */
|
||||||
|
{
|
||||||
|
RuleCounter depcnt;
|
||||||
|
int r = depcnt.wait_result(exec_list(rlist, subdeps, tname));
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
if (ob_check_exec(tname, subdeps)) {
|
if (ob_check_exec(tname, subdeps)) {
|
||||||
if (r) return r;
|
|
||||||
ostd::Uint32 *func = nullptr;
|
ostd::Uint32 *func = nullptr;
|
||||||
for (auto &sr: rlist.iter()) {
|
for (auto &sr: rlist.iter()) {
|
||||||
Rule &r = *sr.rule;
|
Rule &r = *sr.rule;
|
||||||
|
@ -404,8 +459,20 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tpool.init(os.jobs);
|
||||||
|
|
||||||
os.cs.add_command("shell", "C", [](cscript::CsState &cs, char *s) {
|
os.cs.add_command("shell", "C", [](cscript::CsState &cs, char *s) {
|
||||||
cs.result->set_int(system(s));
|
RuleCounter *cnt = counters.back();
|
||||||
|
cnt->incr();
|
||||||
|
char *dup = strdup(s);
|
||||||
|
tpool.push([cnt, dup]() {
|
||||||
|
int ret = system(dup);
|
||||||
|
free(dup);
|
||||||
|
if (ret && !cnt->result)
|
||||||
|
cnt->result = ret;
|
||||||
|
cnt->decr();
|
||||||
|
});
|
||||||
|
cs.result->set_int(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
os.cs.add_command("rule", "sseN", [](cscript::CsState &, const char *tgt,
|
os.cs.add_command("rule", "sseN", [](cscript::CsState &, const char *tgt,
|
||||||
|
@ -436,5 +503,11 @@ int main(int argc, char **argv) {
|
||||||
if (rules.empty())
|
if (rules.empty())
|
||||||
return os.error(1, "no targets");
|
return os.error(1, "no targets");
|
||||||
|
|
||||||
return os.exec_rule((optind < argc) ? argv[optind] : "all");
|
RuleCounter maincnt;
|
||||||
|
int ret = os.exec_rule((optind < argc) ? argv[optind] : "all");
|
||||||
|
ret = maincnt.wait_result(ret);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
tpool.destroy();
|
||||||
|
return 0;
|
||||||
}
|
}
|
9
tpool.hh
9
tpool.hh
|
@ -61,7 +61,7 @@ struct Task {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ThreadPool {
|
struct ThreadPool {
|
||||||
ThreadPool(ostd::Size size): size(size) {}
|
ThreadPool() {}
|
||||||
|
|
||||||
~ThreadPool() {
|
~ThreadPool() {
|
||||||
if (running) destroy();
|
if (running) destroy();
|
||||||
|
@ -72,7 +72,7 @@ struct ThreadPool {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init() {
|
bool init(ostd::Size size) {
|
||||||
running = true;
|
running = true;
|
||||||
for (ostd::Size i = 0; i < size; ++i) {
|
for (ostd::Size i = 0; i < size; ++i) {
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
|
@ -88,9 +88,9 @@ struct ThreadPool {
|
||||||
running = false;
|
running = false;
|
||||||
mtx.unlock();
|
mtx.unlock();
|
||||||
cond.broadcast();
|
cond.broadcast();
|
||||||
for (ostd::Size i = 0; i < size; ++i) {
|
for (pthread_t &tid: thrs.iter()) {
|
||||||
void *ret;
|
void *ret;
|
||||||
pthread_join(thrs[i], &ret);
|
pthread_join(tid, &ret);
|
||||||
cond.broadcast();
|
cond.broadcast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,6 @@ struct ThreadPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ostd::Size size;
|
|
||||||
Cond cond;
|
Cond cond;
|
||||||
Mutex mtx;
|
Mutex mtx;
|
||||||
ostd::Vector<pthread_t> thrs;
|
ostd::Vector<pthread_t> thrs;
|
||||||
|
|
Loading…
Reference in New Issue