summaryrefslogtreecommitdiffstats
path: root/patches/ninja-1.8.2/0004-Honor-lN-from-MAKEFLAGS.patch
blob: 2a250500161cf69ec5835572842f634cc9dd73dd (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
From: Stefan Becker <chemobejk@gmail.com>
Date: Sun, 12 Nov 2017 18:04:12 +0200
Subject: [PATCH] Honor -lN from MAKEFLAGS

This emulates the behaviour of GNU make.

- build: make a copy of max_load_average and pass it to TokenPool.
- GNUmakeTokenPool: if we detect a jobserver and a valid -lN argument in
  MAKEFLAGS then set max_load_average to N.
---
 src/build.cc              | 10 +++++++---
 src/tokenpool-gnu-make.cc | 19 +++++++++++++++----
 src/tokenpool-none.cc     |  2 +-
 src/tokenpool.h           |  2 +-
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/src/build.cc b/src/build.cc
index bc26bdade61b..6eaf299caeec 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -501,13 +501,17 @@ struct RealCommandRunner : public CommandRunner {
   virtual void Abort();
 
   const BuildConfig& config_;
+  // copy of config_.max_load_average; can be modified by TokenPool setup
+  double max_load_average_;
   SubprocessSet subprocs_;
   TokenPool *tokens_;
   map<Subprocess*, Edge*> subproc_to_edge_;
 };
 
 RealCommandRunner::RealCommandRunner(const BuildConfig& config) : config_(config) {
-  tokens_ = TokenPool::Get(config_.parallelism_from_cmdline);
+  max_load_average_ = config.max_load_average;
+  tokens_ = TokenPool::Get(config_.parallelism_from_cmdline,
+                           max_load_average_);
 }
 
 RealCommandRunner::~RealCommandRunner() {
@@ -535,8 +539,8 @@ bool RealCommandRunner::CanRunMore() {
             subprocs_.finished_.size()) < config_.parallelism);
   return parallelism_limit_not_reached
     && (subprocs_.running_.empty() ||
-        (config_.max_load_average <= 0.0f ||
-         GetLoadAverage() < config_.max_load_average));
+        (max_load_average_ <= 0.0f ||
+         GetLoadAverage() < max_load_average_));
 }
 
 bool RealCommandRunner::AcquireToken() {
diff --git a/src/tokenpool-gnu-make.cc b/src/tokenpool-gnu-make.cc
index af4be05a31cf..fb654c4d88ba 100644
--- a/src/tokenpool-gnu-make.cc
+++ b/src/tokenpool-gnu-make.cc
@@ -35,7 +35,7 @@ struct GNUmakeTokenPool : public TokenPool {
   virtual void Clear();
   virtual int GetMonitorFd();
 
-  bool Setup(bool ignore);
+  bool Setup(bool ignore, double& max_load_average);
 
  private:
   int available_;
@@ -100,7 +100,7 @@ bool GNUmakeTokenPool::SetAlarmHandler() {
   }
 }
 
-bool GNUmakeTokenPool::Setup(bool ignore) {
+bool GNUmakeTokenPool::Setup(bool ignore, double& max_load_average) {
   const char *value = getenv("MAKEFLAGS");
   if (value) {
     // GNU make <= 4.1
@@ -118,9 +118,20 @@ bool GNUmakeTokenPool::Setup(bool ignore) {
             CheckFd(rfd) &&
             CheckFd(wfd) &&
             SetAlarmHandler()) {
+          const char *l_arg = strstr(value, " -l");
+          int load_limit = -1;
+
           printf("ninja: using GNU make jobserver.\n");
           rfd_ = rfd;
           wfd_ = wfd;
+
+          // translate GNU make -lN to ninja -lN
+          if (l_arg &&
+              (sscanf(l_arg + 3, "%d ", &load_limit) == 1) &&
+              (load_limit > 0)) {
+            max_load_average = load_limit;
+          }
+
           return true;
         }
       }
@@ -210,9 +221,9 @@ int GNUmakeTokenPool::GetMonitorFd() {
   return(rfd_);
 }
 
-struct TokenPool *TokenPool::Get(bool ignore) {
+struct TokenPool *TokenPool::Get(bool ignore, double& max_load_average) {
   GNUmakeTokenPool *tokenpool = new GNUmakeTokenPool;
-  if (tokenpool->Setup(ignore))
+  if (tokenpool->Setup(ignore, max_load_average))
     return tokenpool;
   else
     delete tokenpool;
diff --git a/src/tokenpool-none.cc b/src/tokenpool-none.cc
index 199b22264bc6..e8e25426c39f 100644
--- a/src/tokenpool-none.cc
+++ b/src/tokenpool-none.cc
@@ -22,6 +22,6 @@
 #include <stdlib.h>
 
 // No-op TokenPool implementation
-struct TokenPool *TokenPool::Get(bool ignore) {
+struct TokenPool *TokenPool::Get(bool ignore, double& max_load_average) {
   return NULL;
 }
diff --git a/src/tokenpool.h b/src/tokenpool.h
index 878a0933c2f0..f9e8cc2ee081 100644
--- a/src/tokenpool.h
+++ b/src/tokenpool.h
@@ -28,5 +28,5 @@ struct TokenPool {
 #endif
 
   // returns NULL if token pool is not available
-  static struct TokenPool *Get(bool ignore);
+  static struct TokenPool *Get(bool ignore, double& max_load_average);
 };