put most state into ObState
parent
080153a373
commit
27605ee5af
177
main.cc
177
main.cc
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue