put most state into ObState

master
Daniel Kolesa 2015-10-16 00:36:39 +02:00
parent 080153a373
commit 27605ee5af
1 changed files with 89 additions and 88 deletions

177
main.cc
View File

@ -25,68 +25,6 @@ using cscript::CsState;
using cscript::TvalRange; using cscript::TvalRange;
using cscript::StackedValue; using cscript::StackedValue;
/* represents a rule definition, possibly with a function */
struct Rule {
String target;
Vector<String> deps;
Uint32 *func;
Rule(): target(), deps(), func(nullptr) {}
Rule(const Rule &r): target(r.target), deps(r.deps), func(r.func) {
cscript::bcode_ref(func);
}
~Rule() { cscript::bcode_unref(func); }
};
static Vector<Rule> rules;
struct RuleCounter;
static 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;
};
static ThreadPool tpool; static ThreadPool tpool;
/* check funcs */ /* check funcs */
@ -159,6 +97,21 @@ struct ObState {
int jobs = 1; int jobs = 1;
bool ignore_env = false; bool ignore_env = false;
/* represents a rule definition, possibly with a function */
struct Rule {
String target;
Vector<String> deps;
Uint32 *func;
Rule(): target(), deps(), func(nullptr) {}
Rule(const Rule &r): target(r.target), deps(r.deps), func(r.func) {
cscript::bcode_ref(func);
}
~Rule() { cscript::bcode_unref(func); }
};
Vector<Rule> rules;
struct SubRule { struct SubRule {
ConstCharRange sub; ConstCharRange sub;
Rule *rule; Rule *rule;
@ -166,6 +119,53 @@ struct ObState {
Map<ConstCharRange, Vector<SubRule>> cache; Map<ConstCharRange, Vector<SubRule>> cache;
struct RuleCounter {
RuleCounter(Vector<RuleCounter *> &ctrs): cond(), mtx(), counter(0),
result(0) {
ctrs.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(Vector<RuleCounter *> &ctrs, int ret) {
ctrs.pop();
if (ret)
return ret;
wait();
ret = result;
if (ret)
return ret;
return 0;
}
Cond cond;
Mutex mtx;
volatile int counter;
ostd::AtomicInt result;
};
Vector<RuleCounter *> counters;
template<typename ...A> template<typename ...A>
int error(int retcode, ConstCharRange fmt, A &&...args) { int error(int retcode, ConstCharRange fmt, A &&...args) {
ostd::err.write(progname, ": "); ostd::err.write(progname, ": ");
@ -199,8 +199,9 @@ struct ObState {
Vector<String> subdeps; Vector<String> subdeps;
/* new scope for early destruction */ /* new scope for early destruction */
{ {
RuleCounter depcnt; RuleCounter depcnt(counters);
int r = depcnt.wait_result(exec_list(rlist, subdeps, tname)); int r = depcnt.wait_result(counters, exec_list(rlist, subdeps,
tname));
if (r) if (r)
return r; return r;
} }
@ -309,6 +310,22 @@ struct ObState {
} }
return exec_func(target, rlist); return exec_func(target, rlist);
} }
void rule_add(const char *tgt, const char *dep, ostd::Uint32 *body) {
auto targets = cscript::util::list_explode(tgt);
auto deps = dep ? cscript::util::list_explode(dep)
: ostd::Vector<ostd::String>();
for (auto &target: targets.iter()) {
Rule &r = rules.push();
r.target = target;
if (body) {
r.func = body;
cscript::bcode_ref(body);
}
for (auto &dep: deps.iter())
r.deps.push(dep);
}
}
}; };
static int ob_print_help(ConstCharRange a0, ostd::Stream &os, int v) { static int ob_print_help(ConstCharRange a0, ostd::Stream &os, int v) {
@ -323,22 +340,6 @@ static int ob_print_help(ConstCharRange a0, ostd::Stream &os, int v) {
return v; return v;
} }
static void rule_add(const char *tgt, const char *dep, ostd::Uint32 *body) {
auto targets = cscript::util::list_explode(tgt);
auto deps = dep ? cscript::util::list_explode(dep)
: ostd::Vector<ostd::String>();
for (auto &target: targets.iter()) {
Rule &r = rules.push();
r.target = target;
if (body) {
r.func = body;
cscript::bcode_ref(body);
}
for (auto &dep: deps.iter())
r.deps.push(dep);
}
};
int main(int argc, char **argv) { int main(int argc, char **argv) {
ObState os; ObState os;
ConstCharRange pn = argv[0]; ConstCharRange pn = argv[0];
@ -395,7 +396,7 @@ int main(int argc, char **argv) {
tpool.init(os.jobs); tpool.init(os.jobs);
os.cs.add_command("shell", "C", [](CsState &cs, ConstCharRange s) { os.cs.add_command("shell", "C", [](CsState &cs, ConstCharRange s) {
RuleCounter *cnt = counters.back(); auto cnt = ((ObState &)cs).counters.back();
cnt->incr(); cnt->incr();
char *ds = String(s).disown(); char *ds = String(s).disown();
tpool.push([cnt, ds]() { tpool.push([cnt, ds]() {
@ -408,15 +409,15 @@ int main(int argc, char **argv) {
cs.result->set_int(0); cs.result->set_int(0);
}); });
os.cs.add_command("rule", "sseN", [](CsState &, const char *tgt, os.cs.add_command("rule", "sseN", [](CsState &cs, const char *tgt,
const char *dep, ostd::Uint32 *body, const char *dep, ostd::Uint32 *body,
int *numargs) { int *numargs) {
rule_add(tgt, dep, (*numargs > 2) ? body : nullptr); ((ObState &)cs).rule_add(tgt, dep, (*numargs > 2) ? body : nullptr);
}); });
os.cs.add_command("rule-", "seN", [](CsState &, const char *tgt, os.cs.add_command("rule-", "seN", [](CsState &cs, const char *tgt,
ostd::Uint32 *body, int *numargs) { ostd::Uint32 *body, int *numargs) {
rule_add(tgt, nullptr, (*numargs > 1) ? body : nullptr); ((ObState &)cs).rule_add(tgt, nullptr, (*numargs > 1) ? body : nullptr);
}); });
os.cs.add_commandn("getenv", "s", [](CsState &cs, TvalRange args) { os.cs.add_commandn("getenv", "s", [](CsState &cs, TvalRange args) {
@ -437,12 +438,12 @@ int main(int argc, char **argv) {
if ((!fcont.empty() && !os.cs.run_bool(fcont)) || !os.cs.run_file(fname)) if ((!fcont.empty() && !os.cs.run_bool(fcont)) || !os.cs.run_file(fname))
return os.error(1, "failed creating rules"); return os.error(1, "failed creating rules");
if (rules.empty()) if (os.rules.empty())
return os.error(1, "no targets"); return os.error(1, "no targets");
RuleCounter maincnt; ObState::RuleCounter maincnt(os.counters);
int ret = os.exec_rule((optind < argc) ? argv[optind] : "all"); int ret = os.exec_rule((optind < argc) ? argv[optind] : "all");
ret = maincnt.wait_result(ret); ret = maincnt.wait_result(os.counters, ret);
if (ret) if (ret)
return ret; return ret;
tpool.destroy(); tpool.destroy();