summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Iannucci <robbie@rail.com>2012-10-03 23:27:27 (GMT)
committerRobert A Iannucci Jr <iannucci@chromium.org>2012-11-09 04:25:39 (GMT)
commitaca4ec54656057e58ca7a9ae5de7f94c869b2ccb (patch)
tree4dc557e0df2399092aa6e782f86dae7aa72895a0
parenta4220cdcd298cb43133c241497f2edb9e5cbc8d9 (diff)
downloadNinja-aca4ec54656057e58ca7a9ae5de7f94c869b2ccb.zip
Ninja-aca4ec54656057e58ca7a9ae5de7f94c869b2ccb.tar.gz
Ninja-aca4ec54656057e58ca7a9ae5de7f94c869b2ccb.tar.bz2
stub out an api and de-constify Pool
-rw-r--r--src/build.cc24
-rw-r--r--src/build.h8
-rw-r--r--src/graph.h2
-rw-r--r--src/manifest_parser.cc2
-rw-r--r--src/state.cc12
-rw-r--r--src/state.h32
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<Node*>* 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<Edge*, bool>::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<Node*>::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 <cstdio>
#include <map>
+#include <memory>
+#include <queue>
#include <set>
#include <string>
-#include <queue>
#include <vector>
-#include <memory>
-#include <cstdio>
#include "graph.h" // XXX needed for DependencyScan; should rearrange.
#include "exit_status.h"
@@ -69,6 +69,8 @@ private:
bool AddSubTarget(Node* node, vector<Node*>* stack, string* err);
bool CheckDependencyCycle(Node* node, vector<Node*>* 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<Node*> inputs_;
vector<Node*> 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<EvalString>::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<string, const Pool*>::iterator i = pools_.find(pool_name);
+Pool* State::LookupPool(const string& pool_name) {
+ map<string, Pool*>::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 <map>
+#include <queue>
+#include <set>
#include <string>
#include <vector>
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<Edge*>* ready_queue);
+
private:
string name_;
+ int current_use_;
int depth_;
+
+ queue<Edge*> 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<string, const Rule*> rules_;
/// All the pools used in the graph.
- map<string, const Pool*> pools_;
+ map<string, Pool*> pools_;
/// All the edges of the graph.
vector<Edge*> edges_;