summaryrefslogtreecommitdiffstats
path: root/patches/ninja-1.8.2/0003-Ignore-jobserver-when-jN-is-forced-on-command-line.patch
blob: cd4b78f69bb71dc19e7d511ba0f581b5aa5fa804 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
From: Stefan Becker <chemobejk@gmail.com>
Date: Sun, 12 Nov 2017 16:58:55 +0200
Subject: [PATCH] Ignore jobserver when -jN is forced on command line

This emulates the behaviour of GNU make.

- add parallelism_from_cmdline flag to build configuration
- set the flag when -jN is given on command line
- pass the flag to TokenPool::Get()
- GNUmakeTokenPool::Setup()
  * prints a warning when the flag is true and jobserver was detected
  * returns false, i.e. jobserver will be ignored
- ignore config.parallelism in CanRunMore() when we have a valid
  TokenPool, because it gets always initialized to a default when not
  given on the command line
---
 src/build.cc              | 10 ++++++----
 src/build.h               |  4 +++-
 src/ninja.cc              |  1 +
 src/tokenpool-gnu-make.cc | 34 +++++++++++++++++++---------------
 src/tokenpool-none.cc     |  4 ++--
 src/tokenpool.h           |  4 ++--
 6 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/src/build.cc b/src/build.cc
index 219bb9f1ff48..bc26bdade61b 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -507,7 +507,7 @@ struct RealCommandRunner : public CommandRunner {
 };
 
 RealCommandRunner::RealCommandRunner(const BuildConfig& config) : config_(config) {
-  tokens_ = TokenPool::Get();
+  tokens_ = TokenPool::Get(config_.parallelism_from_cmdline);
 }
 
 RealCommandRunner::~RealCommandRunner() {
@@ -529,9 +529,11 @@ void RealCommandRunner::Abort() {
 }
 
 bool RealCommandRunner::CanRunMore() {
-  size_t subproc_number =
-      subprocs_.running_.size() + subprocs_.finished_.size();
-  return (int)subproc_number < config_.parallelism
+  bool parallelism_limit_not_reached =
+    tokens_ || // ignore config_.parallelism
+    ((int) (subprocs_.running_.size() +
+            subprocs_.finished_.size()) < config_.parallelism);
+  return parallelism_limit_not_reached
     && (subprocs_.running_.empty() ||
         (config_.max_load_average <= 0.0f ||
          GetLoadAverage() < config_.max_load_average));
diff --git a/src/build.h b/src/build.h
index ca605e62e0e3..6bc6fea26e94 100644
--- a/src/build.h
+++ b/src/build.h
@@ -128,7 +128,8 @@ struct CommandRunner {
 
 /// Options (e.g. verbosity, parallelism) passed to a build.
 struct BuildConfig {
-  BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1),
+  BuildConfig() : verbosity(NORMAL), dry_run(false),
+                  parallelism(1), parallelism_from_cmdline(false),
                   failures_allowed(1), max_load_average(-0.0f) {}
 
   enum Verbosity {
@@ -139,6 +140,7 @@ struct BuildConfig {
   Verbosity verbosity;
   bool dry_run;
   int parallelism;
+  bool parallelism_from_cmdline;
   int failures_allowed;
   /// The maximum load average we must not exceed. A negative value
   /// means that we do not have any limit.
diff --git a/src/ninja.cc b/src/ninja.cc
index ed004ac8f1fe..4332636c1b64 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -1063,6 +1063,7 @@ int ReadFlags(int* argc, char*** argv,
         if (*end != 0 || value <= 0)
           Fatal("invalid -j parameter");
         config->parallelism = value;
+        config->parallelism_from_cmdline = true;
         break;
       }
       case 'k': {
diff --git a/src/tokenpool-gnu-make.cc b/src/tokenpool-gnu-make.cc
index 396bb7d87443..af4be05a31cf 100644
--- a/src/tokenpool-gnu-make.cc
+++ b/src/tokenpool-gnu-make.cc
@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016-2017 Google Inc. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ struct GNUmakeTokenPool : public TokenPool {
   virtual void Clear();
   virtual int GetMonitorFd();
 
-  bool Setup();
+  bool Setup(bool ignore);
 
  private:
   int available_;
@@ -100,7 +100,7 @@ bool GNUmakeTokenPool::SetAlarmHandler() {
   }
 }
 
-bool GNUmakeTokenPool::Setup() {
+bool GNUmakeTokenPool::Setup(bool ignore) {
   const char *value = getenv("MAKEFLAGS");
   if (value) {
     // GNU make <= 4.1
@@ -109,16 +109,20 @@ bool GNUmakeTokenPool::Setup() {
     if (!jobserver)
       jobserver = strstr(value, "--jobserver-auth=");
     if (jobserver) {
-      int rfd = -1;
-      int wfd = -1;
-      if ((sscanf(jobserver, "%*[^=]=%d,%d", &rfd, &wfd) == 2) &&
-          CheckFd(rfd) &&
-          CheckFd(wfd) &&
-          SetAlarmHandler()) {
-        printf("ninja: using GNU make jobserver.\n");
-        rfd_ = rfd;
-        wfd_ = wfd;
-        return true;
+      if (ignore) {
+        printf("ninja: warning: -jN forced on command line; ignoring GNU make jobserver.\n");
+      } else {
+        int rfd = -1;
+        int wfd = -1;
+        if ((sscanf(jobserver, "%*[^=]=%d,%d", &rfd, &wfd) == 2) &&
+            CheckFd(rfd) &&
+            CheckFd(wfd) &&
+            SetAlarmHandler()) {
+          printf("ninja: using GNU make jobserver.\n");
+          rfd_ = rfd;
+          wfd_ = wfd;
+          return true;
+        }
       }
     }
   }
@@ -206,9 +210,9 @@ int GNUmakeTokenPool::GetMonitorFd() {
   return(rfd_);
 }
 
-struct TokenPool *TokenPool::Get(void) {
+struct TokenPool *TokenPool::Get(bool ignore) {
   GNUmakeTokenPool *tokenpool = new GNUmakeTokenPool;
-  if (tokenpool->Setup())
+  if (tokenpool->Setup(ignore))
     return tokenpool;
   else
     delete tokenpool;
diff --git a/src/tokenpool-none.cc b/src/tokenpool-none.cc
index 602b3316f54d..199b22264bc6 100644
--- a/src/tokenpool-none.cc
+++ b/src/tokenpool-none.cc
@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016-2017 Google Inc. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -22,6 +22,6 @@
 #include <stdlib.h>
 
 // No-op TokenPool implementation
-struct TokenPool *TokenPool::Get(void) {
+struct TokenPool *TokenPool::Get(bool ignore) {
   return NULL;
 }
diff --git a/src/tokenpool.h b/src/tokenpool.h
index 301e1998ee8e..878a0933c2f0 100644
--- a/src/tokenpool.h
+++ b/src/tokenpool.h
@@ -1,4 +1,4 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
+// Copyright 2016-2017 Google Inc. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -28,5 +28,5 @@ struct TokenPool {
 #endif
 
   // returns NULL if token pool is not available
-  static struct TokenPool *Get(void);
+  static struct TokenPool *Get(bool ignore);
 };