Ninja
real_command_runner.cc
Go to the documentation of this file.
1// Copyright 2011 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "build.h"
16#include "jobserver.h"
17#include "limits.h"
18#include "subprocess.h"
19
21 explicit RealCommandRunner(const BuildConfig& config,
22 Jobserver::Client* jobserver)
23 : config_(config), jobserver_(jobserver) {}
24 size_t CanRunMore() const override;
25 bool StartCommand(Edge* edge) override;
26 bool WaitForCommand(Result* result) override;
27 std::vector<Edge*> GetActiveEdges() override;
28 void Abort() override;
29
31 if (jobserver_) {
32 for (Edge* edge : GetActiveEdges()) {
33 jobserver_->Release(std::move(edge->job_slot_));
34 }
35 }
36 }
37
41 std::map<const Subprocess*, Edge*> subproc_to_edge_;
42};
43
45 std::vector<Edge*> edges;
46 for (std::map<const Subprocess*, Edge*>::iterator e =
47 subproc_to_edge_.begin();
48 e != subproc_to_edge_.end(); ++e)
49 edges.push_back(e->second);
50 return edges;
51}
52
55 subprocs_.Clear();
56}
57
59 size_t subproc_number =
60 subprocs_.running_.size() + subprocs_.finished_.size();
61
62 int64_t capacity = config_.parallelism - subproc_number;
63
64 if (jobserver_) {
65 // When a jobserver token pool is used, make the
66 // capacity infinite, and let FindWork() limit jobs
67 // through token acquisitions instead.
68 capacity = INT_MAX;
69 }
70
71 if (config_.max_load_average > 0.0f) {
72 int load_capacity = config_.max_load_average - GetLoadAverage();
73 if (load_capacity < capacity)
74 capacity = load_capacity;
75 }
76
77 if (capacity < 0)
78 capacity = 0;
79
80 if (capacity == 0 && subprocs_.running_.empty())
81 // Ensure that we make progress.
82 capacity = 1;
83
84 return capacity;
85}
86
88 std::string command = edge->EvaluateCommand();
89 Subprocess* subproc = subprocs_.Add(command, edge->use_console());
90 if (!subproc)
91 return false;
92 subproc_to_edge_.insert(std::make_pair(subproc, edge));
93
94 return true;
95}
96
98 Subprocess* subproc;
99 while ((subproc = subprocs_.NextFinished()) == NULL) {
100 bool interrupted = subprocs_.DoWork();
101 if (interrupted)
102 return false;
103 }
104
105 result->status = subproc->Finish();
106 result->output = subproc->GetOutput();
107
108 std::map<const Subprocess*, Edge*>::iterator e =
109 subproc_to_edge_.find(subproc);
110 result->edge = e->second;
111 subproc_to_edge_.erase(e);
112
113 delete subproc;
114 return true;
115}
116
118 Jobserver::Client* jobserver) {
119 return new RealCommandRunner(config, jobserver);
120}
A Jobserver::Client instance models a client of an external GNU jobserver pool, which can be implemen...
Definition jobserver.h:189
Options (e.g. verbosity, parallelism) passed to a build.
Definition build.h:176
The result of waiting for a command.
Definition build.h:156
ExitStatus status
Definition build.h:159
std::string output
Definition build.h:160
CommandRunner is an interface that wraps running the build subcommands.
Definition build.h:150
static CommandRunner * factory(const BuildConfig &config, Jobserver::Client *jobserver)
Creates the RealCommandRunner.
An edge in the dependency graph; links between Nodes using Rules.
Definition graph.h:175
std::string EvaluateCommand(bool incl_rsp_file=false) const
Expand all variables in a command and return it as a string.
Definition graph.cc:501
bool use_console() const
Definition graph.cc:567
std::vector< Edge * > GetActiveEdges() override
Jobserver::Client * jobserver_
bool WaitForCommand(Result *result) override
Wait for a command to complete, or return false if interrupted.
bool StartCommand(Edge *edge) override
RealCommandRunner(const BuildConfig &config, Jobserver::Client *jobserver)
size_t CanRunMore() const override
const BuildConfig & config_
std::map< const Subprocess *, Edge * > subproc_to_edge_
SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
Definition subprocess.h:101
Subprocess wraps a single async subprocess.
Definition subprocess.h:42
ExitStatus Finish()
Returns ExitSuccess on successful process exit, ExitInterrupted if the process was interrupted,...
const std::string & GetOutput() const
double GetLoadAverage()
Definition util.cc:981
signed long long int64_t
A 64-bit integer type.
Definition win32port.h:28