From aca4ec54656057e58ca7a9ae5de7f94c869b2ccb Mon Sep 17 00:00:00 2001 From: Robert Iannucci Date: Wed, 3 Oct 2012 16:27:27 -0700 Subject: stub out an api and de-constify Pool --- src/build.cc | 24 ++++++++++++++++++++++-- src/build.h | 8 +++++--- src/graph.h | 2 ++ src/manifest_parser.cc | 2 +- src/state.cc | 12 ++++++------ src/state.h | 32 +++++++++++++++++++++++++++----- 6 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/build.cc b/src/build.cc index 19775e7..0710e51 100644 --- a/src/build.cc +++ b/src/build.cc @@ -359,7 +359,7 @@ bool Plan::AddSubTarget(Node* node, vector* stack, string* err) { want = true; ++wanted_edges_; if (edge->AllInputsReady()) - ready_.insert(edge); + ScheduleWork(edge); if (!edge->is_phony()) ++command_edges_; } @@ -408,6 +408,22 @@ Edge* Plan::FindWork() { return edge; } +void Plan::ScheduleWork(Edge* edge) { + // TODO(iannucci): See if this should get delayed instead + // if edge has pool + // create pool if DNE + // pool.InsertEdge(edge) + // ready_.insert(pool.GetAvailableEdges()) + // else + ready_.insert(edge); +} + +void Plan::ResumeDelayedJobs(Edge* edge) { + // if edge has pool + // pool.ReturnUnits(edge) + // ready_.insert(pool.GetAvailableEdges()) +} + void Plan::EdgeFinished(Edge* edge) { map::iterator i = want_.find(edge); assert(i != want_.end()); @@ -416,6 +432,9 @@ void Plan::EdgeFinished(Edge* edge) { want_.erase(i); edge->outputs_ready_ = true; + // See if this job frees up any delayed jobs + ResumeDelayedJobs(edge); + // Check off any nodes we were waiting for with this edge. for (vector::iterator i = edge->outputs_.begin(); i != edge->outputs_.end(); ++i) { @@ -434,7 +453,7 @@ void Plan::NodeFinished(Node* node) { // See if the edge is now ready. if ((*i)->AllInputsReady()) { if (want_i->second) { - ready_.insert(*i); + ScheduleWork(*i); } else { // We do not need to build this edge, but we might need to build one of // its dependents. @@ -501,6 +520,7 @@ void Plan::Dump() { printf("want "); i->first->Dump(); } + // TODO(iannucci): Dump pending pools too printf("ready: %d\n", (int)ready_.size()); } diff --git a/src/build.h b/src/build.h index 8876d88..6bcfc07 100644 --- a/src/build.h +++ b/src/build.h @@ -15,13 +15,13 @@ #ifndef NINJA_BUILD_H_ #define NINJA_BUILD_H_ +#include #include +#include +#include #include #include -#include #include -#include -#include #include "graph.h" // XXX needed for DependencyScan; should rearrange. #include "exit_status.h" @@ -69,6 +69,8 @@ private: bool AddSubTarget(Node* node, vector* stack, string* err); bool CheckDependencyCycle(Node* node, vector* stack, string* err); void NodeFinished(Node* node); + void ScheduleWork(Edge* edge); + void ResumeDelayedJobs(Edge* edge); /// Keep track of which edges we want to build in this plan. If this map does /// not contain an entry for an edge, we do not want to build the entry or its diff --git a/src/graph.h b/src/graph.h index 272fcb9..a35ab65 100644 --- a/src/graph.h +++ b/src/graph.h @@ -138,6 +138,7 @@ struct Rule { struct BuildLog; struct Node; struct State; +struct Pool; /// An edge in the dependency graph; links between Nodes using Rules. struct Edge { @@ -166,6 +167,7 @@ struct Edge { void Dump(const char* prefix="") const; const Rule* rule_; + Pool* pool_; vector inputs_; vector outputs_; Env* env_; diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc index 405e244..8a010dd 100644 --- a/src/manifest_parser.cc +++ b/src/manifest_parser.cc @@ -266,7 +266,7 @@ bool ManifestParser::ParseEdge(string* err) { } while (lexer_.PeekToken(Lexer::INDENT)); } - Edge* edge = state_->AddEdge(rule); + Edge* edge = state_->AddEdge(rule, NULL); edge->env_ = env; for (vector::iterator i = ins.begin(); i != ins.end(); ++i) { string path = i->Evaluate(env); diff --git a/src/state.cc b/src/state.cc index 0697e48..e8e6dc3 100644 --- a/src/state.cc +++ b/src/state.cc @@ -22,7 +22,7 @@ #include "metrics.h" #include "util.h" -const Pool State::kDefaultPool("", 0); +Pool State::kDefaultPool("", 0); const Rule State::kPhonyRule("phony"); State::State() { @@ -42,22 +42,22 @@ const Rule* State::LookupRule(const string& rule_name) { return i->second; } -void State::AddPool(const Pool* pool) { +void State::AddPool(Pool* pool) { assert(LookupPool(pool->name()) == NULL); pools_[pool->name()] = pool; } -const Pool* State::LookupPool(const string& pool_name) { - map::iterator i = pools_.find(pool_name); +Pool* State::LookupPool(const string& pool_name) { + map::iterator i = pools_.find(pool_name); if (i == pools_.end()) return NULL; return i->second; } -Edge* State::AddEdge(const Rule* rule, const Pool* pool) { - // FIXME(iannucci): do something with pool +Edge* State::AddEdge(const Rule* rule, Pool* pool) { Edge* edge = new Edge(); edge->rule_ = rule; + edge->pool_ = pool; edge->env_ = &bindings_; edges_.push_back(edge); return edge; diff --git a/src/state.h b/src/state.h index e678df9..3e569cf 100644 --- a/src/state.h +++ b/src/state.h @@ -16,6 +16,8 @@ #define NINJA_STATE_H_ #include +#include +#include #include #include using namespace std; @@ -37,26 +39,46 @@ struct Pool { int depth() const { return depth_; } const string& name() const { return name_; } + /// true if the Pool would delay this edge + bool ShouldDelayEdge(Edge* edge); + + /// informs this Pool that the given edge is committed to be run. + /// Pool will count this edge as using resources from this pool. + void EdgeScheduled(Edge* edge); + + /// informs this Pool that the given edge is no longer runnable, and should + /// relinquish it's resources back to the pool + void EdgeFinished(Edge* edge); + + /// adds the given edge to this Pool to be delayed. + void DelayEdge(Edge* edge); + + /// Pool will add zero or more edges to the ready_queue + void RetrieveReadyEdges(Edge* edge, set* ready_queue); + private: string name_; + int current_use_; int depth_; + + queue delayed_; }; /// Global state (file status, loaded rules) for a single run. struct State { + static Pool kDefaultPool; static const Rule kPhonyRule; - static const Pool kDefaultPool; State(); void AddRule(const Rule* rule); const Rule* LookupRule(const string& rule_name); - void AddPool(const Pool* pool); - const Pool* LookupPool(const string& pool_name); + void AddPool(Pool* pool); + Pool* LookupPool(const string& pool_name); - Edge* AddEdge(const Rule* rule, const Pool* pool); + Edge* AddEdge(const Rule* rule, Pool* pool); Node* GetNode(StringPiece path); Node* LookupNode(StringPiece path); @@ -86,7 +108,7 @@ struct State { map rules_; /// All the pools used in the graph. - map pools_; + map pools_; /// All the edges of the graph. vector edges_; -- cgit v0.12