Coverage Report

Created: 2025-08-03 09:15

/src/ninja/src/state.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef NINJA_STATE_H_
16
#define NINJA_STATE_H_
17
18
#include <map>
19
#include <set>
20
#include <string>
21
#include <vector>
22
23
#include "eval_env.h"
24
#include "graph.h"
25
#include "hash_map.h"
26
#include "util.h"
27
28
struct Edge;
29
struct Node;
30
struct Rule;
31
32
/// A pool for delayed edges.
33
/// Pools are scoped to a State. Edges within a State will share Pools. A Pool
34
/// will keep a count of the total 'weight' of the currently scheduled edges. If
35
/// a Plan attempts to schedule an Edge which would cause the total weight to
36
/// exceed the depth of the Pool, the Pool will enqueue the Edge instead of
37
/// allowing the Plan to schedule it. The Pool will relinquish queued Edges when
38
/// the total scheduled weight diminishes enough (i.e. when a scheduled edge
39
/// completes).
40
struct Pool {
41
  Pool(const std::string& name, int depth)
42
152
    : name_(name), current_use_(0), depth_(depth), delayed_() {}
43
44
  // A depth of 0 is infinite
45
0
  bool is_valid() const { return depth_ >= 0; }
46
0
  int depth() const { return depth_; }
47
1.33k
  const std::string& name() const { return name_; }
48
0
  int current_use() const { return current_use_; }
49
50
  /// true if the Pool might delay this edge
51
0
  bool ShouldDelayEdge() const { return depth_ != 0; }
52
53
  /// informs this Pool that the given edge is committed to be run.
54
  /// Pool will count this edge as using resources from this pool.
55
  void EdgeScheduled(const Edge& edge);
56
57
  /// informs this Pool that the given edge is no longer runnable, and should
58
  /// relinquish its resources back to the pool
59
  void EdgeFinished(const Edge& edge);
60
61
  /// adds the given edge to this Pool to be delayed.
62
  void DelayEdge(Edge* edge);
63
64
  /// Pool will add zero or more edges to the ready_queue
65
  void RetrieveReadyEdges(EdgePriorityQueue* ready_queue);
66
67
  /// Dump the Pool and its edges (useful for debugging).
68
  void Dump() const;
69
70
 private:
71
  std::string name_;
72
73
  /// |current_use_| is the total of the weights of the edges which are
74
  /// currently scheduled in the Plan (i.e. the edges in Plan::ready_).
75
  int current_use_;
76
  int depth_;
77
78
  struct WeightedEdgeCmp {
79
0
    bool operator()(const Edge* a, const Edge* b) const {
80
0
      if (!a) return b;
81
0
      if (!b) return false;
82
0
      int weight_diff = a->weight() - b->weight();
83
0
      if (weight_diff != 0) {
84
0
        return weight_diff < 0;
85
0
      }
86
0
      return EdgePriorityGreater()(a, b);
87
0
    }
88
  };
89
90
  typedef std::set<Edge*, WeightedEdgeCmp> DelayedEdges;
91
  DelayedEdges delayed_;
92
};
93
94
/// Global state (file status) for a single run.
95
struct State {
96
  static Pool kDefaultPool;
97
  static Pool kConsolePool;
98
99
  State();
100
101
  void AddPool(Pool* pool);
102
  Pool* LookupPool(const std::string& pool_name);
103
104
  Edge* AddEdge(const Rule* rule);
105
106
  Node* GetNode(StringPiece path, uint64_t slash_bits);
107
  Node* LookupNode(StringPiece path) const;
108
  Node* SpellcheckNode(const std::string& path);
109
110
  /// Add input / output / validation nodes to a given edge. This also
111
  /// ensures that the generated_by_dep_loader() flag for all these nodes
112
  /// is set to false, to indicate that they come from the input manifest.
113
  void AddIn(Edge* edge, StringPiece path, uint64_t slash_bits);
114
  bool AddOut(Edge* edge, StringPiece path, uint64_t slash_bits, std::string* err);
115
  void AddValidation(Edge* edge, StringPiece path, uint64_t slash_bits);
116
  bool AddDefault(StringPiece path, std::string* error);
117
118
  /// Reset state.  Keeps all nodes and edges, but restores them to the
119
  /// state where we haven't yet examined the disk for dirty state.
120
  void Reset();
121
122
  /// Dump the nodes and Pools (useful for debugging).
123
  void Dump();
124
125
  /// @return the root node(s) of the graph. (Root nodes have no output edges).
126
  /// @param error where to write the error message if somethings went wrong.
127
  std::vector<Node*> RootNodes(std::string* error) const;
128
  std::vector<Node*> DefaultNodes(std::string* error) const;
129
130
  /// Mapping of path -> Node.
131
  typedef ExternalStringHashMap<Node*>::Type Paths;
132
  Paths paths_;
133
134
  /// All the pools used in the graph.
135
  std::map<std::string, Pool*> pools_;
136
137
  /// All the edges of the graph.
138
  std::vector<Edge*> edges_;
139
140
  BindingEnv bindings_;
141
  std::vector<Node*> defaults_;
142
};
143
144
#endif  // NINJA_STATE_H_