Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2024-10-15 19:28:03 +08:00
commit 8cdf691d8c
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
8 changed files with 317 additions and 147 deletions

View File

@ -0,0 +1,24 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 15 Oct 2024 10:13:55 +0200
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory corruption during fq
dma init
The loop responsible for allocating up to MTK_FQ_DMA_LENGTH buffers must
only touch as many descriptors, otherwise it ends up corrupting unrelated
memory. Fix the loop iteration count accordingly.
Fixes: c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer size soc specific")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1172,7 +1172,7 @@ static int mtk_init_fq_dma(struct mtk_et
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
return -ENOMEM;
- for (i = 0; i < cnt; i++) {
+ for (i = 0; i < len; i++) {
struct mtk_tx_dma_v2 *txd;
txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;

View File

@ -75,8 +75,8 @@ platform_do_upgrade() {
;;
iptime,nas1dual)
PART_NAME=firmware
default_do_upgrade "$1"
;;
linksys,wrt1200ac|\
linksys,wrt1900ac-v1|\
linksys,wrt1900ac-v2|\

View File

@ -8,7 +8,7 @@ ARCH:=powerpc64
BOARD:=qoriq
BOARDNAME:=NXP QorIQ (PowerPC)
CPU_TYPE:=e5500
FEATURES:=boot-part ext4 fpu legacy-sdcard powerpc64 ramdisk rootfs-part rtc
FEATURES:=boot-part ext4 fpu legacy-sdcard powerpc64 ramdisk rootfs-part rtc squashfs
SUBTARGETS:=generic
KERNEL_PATCHVER:=6.6

View File

@ -103,6 +103,7 @@ CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DMA_OPS=y
CONFIG_DMA_OPS_BYPASS=y
# CONFIG_DRM_OFDRM is not set
CONFIG_DTC=y
CONFIG_DUMMY_CONSOLE=y
# CONFIG_E5500_CPU is not set

View File

@ -1,38 +1,35 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ninja
PKG_VERSION:=1.11.1
PKG_VERSION:=1.12.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/ninja-build/ninja/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=31747ae633213f1eda3842686f83c2aa1412e0f5691d1c14dbbcc67fe7400cea
PKG_HASH:=821bdff48a3f683bc4bb3b6f0b5fe7b2d647cf65d52aeb63328c91a6c6df285a
include $(INCLUDE_DIR)/host-build.mk
CONFIGURE_ARGS:=
ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
CONFIGURE_ARGS+=--verbose
endif
define Host/Configure
cd $(HOST_BUILD_DIR) && \
$(HOST_MAKE_VARS) \
CXX="$(HOSTCXX_NOCACHE)" \
$(STAGING_DIR_HOST)/bin/$(PYTHON) configure.py \
$(if $(shell $(STAGING_DIR_HOST)/bin/ninja --version),,--bootstrap) \
--no-rebuild \
--verbose
-$(Host/Install)
endef
define Host/Compile
cd $(HOST_BUILD_DIR) && \
CXX="$(HOSTCXX_NOCACHE)" \
CXXFLAGS="$(HOST_CXXFLAGS) $(HOST_CPPFLAGS)" \
LDFLAGS="$(HOST_LDFLAGS)" \
$(STAGING_DIR_HOST)/bin/$(PYTHON) configure.py --bootstrap $(CONFIGURE_ARGS)
+$(NINJA) -C $(HOST_BUILD_DIR)
endef
define Host/Install
$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
$(INSTALL_BIN) $(HOST_BUILD_DIR)/ninja $(STAGING_DIR_HOST)/bin/
endef
define Host/Clean
$(call Host/Clean/Default)
rm -f $(STAGING_DIR_HOST)/bin/ninja
endef

View File

@ -0,0 +1,153 @@
From afcd4a146fb82843f6ff695f89504ce4ca65ddfd Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <digit+github@google.com>
Date: Sun, 12 May 2024 23:45:28 +0200
Subject: [PATCH] configure.py: Support --gtest-source-dir to build tests.
Allow the Ninja build plan generated by configure.py to
build `ninja_test` by compiling GoogleTest from source if
the path to the library if passed through the new option
`--gtest-source-dir` or the GTEST_SOURCE_DIR environment
variable.
For simplicity, probing for an installed version of the
library, and linking to it, is not supported (use the
CMake build for this).
This also removes the obsolete `--gtest-dir` option.
+ Update README.md
Fixes #2447
---
README.md | 13 ++++++++
configure.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 95 insertions(+), 1 deletion(-)
--- a/README.md
+++ b/README.md
@@ -34,6 +34,19 @@ via CMake. For more details see
This will generate the `ninja` binary and a `build.ninja` file you can now use
to build Ninja with itself.
+If you have a GoogleTest source directory, you can build the tests
+by passing its path with `--gtest-source-dir=PATH` option, or the
+`GTEST_SOURCE_DIR` environment variable, e.g.:
+
+```
+./configure.py --bootstrap --gtest-source-dir=/path/to/googletest
+./ninja all # build ninja_test and other auxiliary binaries
+./ninja_test` # run the unit-test suite.
+```
+
+Use the CMake build below if you want to use a preinstalled binary
+version of the library.
+
### CMake
```
--- a/configure.py
+++ b/configure.py
@@ -213,7 +213,10 @@ parser.add_option('--debug', action='sto
parser.add_option('--profile', metavar='TYPE',
choices=profilers,
help='enable profiling (' + '/'.join(profilers) + ')',)
-parser.add_option('--with-gtest', metavar='PATH', help='ignored')
+parser.add_option('--gtest-source-dir', metavar='PATH',
+ help='Path to GoogleTest source directory. If not provided ' +
+ 'GTEST_SOURCE_DIR will be probed in the environment. ' +
+ 'Tests will not be built without a value.')
parser.add_option('--with-python', metavar='EXE',
help='use EXE as the Python interpreter',
default=os.path.basename(sys.executable))
@@ -425,6 +428,7 @@ n.variable('cflags', ' '.join(shell_esca
if 'LDFLAGS' in configure_env:
ldflags.append(configure_env['LDFLAGS'])
n.variable('ldflags', ' '.join(shell_escape(flag) for flag in ldflags))
+
n.newline()
if platform.is_msvc():
@@ -582,6 +586,83 @@ if options.bootstrap:
# build.ninja file.
n = ninja_writer
+# Build the ninja_test executable only if the GTest source directory
+# is provided explicitly. Either from the environment with GTEST_SOURCE_DIR
+# or with the --gtest-source-dir command-line option.
+#
+# Do not try to look for an installed binary version, and link against it
+# because doing so properly is platform-specific (use the CMake build for
+# this).
+if options.gtest_source_dir:
+ gtest_src_dir = options.gtest_source_dir
+else:
+ gtest_src_dir = os.environ.get('GTEST_SOURCE_DIR')
+
+if gtest_src_dir:
+ # Verify GoogleTest source directory, and add its include directory
+ # to the global include search path (even for non-test sources) to
+ # keep the build plan generation simple.
+ gtest_all_cc = os.path.join(gtest_src_dir, 'googletest', 'src', 'gtest-all.cc')
+ if not os.path.exists(gtest_all_cc):
+ print('ERROR: Missing GoogleTest source file: %s' % gtest_all_cc)
+ sys.exit(1)
+
+ n.comment('Tests all build into ninja_test executable.')
+
+ # Test-specific version of cflags, must include the GoogleTest
+ # include directory. Also GoogleTest can only build with a C++14 compiler.
+ test_cflags = [f.replace('std=c++11', 'std=c++14') for f in cflags]
+ test_cflags.append('-I' + os.path.join(gtest_src_dir, 'googletest', 'include'))
+
+ test_variables = [('cflags', test_cflags)]
+ if platform.is_msvc():
+ test_variables += [('pdb', 'ninja_test.pdb')]
+
+ test_names = [
+ 'build_log_test',
+ 'build_test',
+ 'clean_test',
+ 'clparser_test',
+ 'depfile_parser_test',
+ 'deps_log_test',
+ 'disk_interface_test',
+ 'dyndep_parser_test',
+ 'edit_distance_test',
+ 'graph_test',
+ 'json_test',
+ 'lexer_test',
+ 'manifest_parser_test',
+ 'ninja_test',
+ 'state_test',
+ 'string_piece_util_test',
+ 'subprocess_test',
+ 'test',
+ 'util_test',
+ ]
+ if platform.is_windows():
+ test_names += [
+ 'includes_normalize_test',
+ 'msvc_helper_test',
+ ]
+
+ objs = []
+ for name in test_names:
+ objs += cxx(name, variables=test_variables)
+
+ # Build GTest as a monolithic source file.
+ # This requires one extra include search path, so replace the
+ # value of 'cflags' in our list.
+ gtest_all_variables = test_variables[1:] + [
+ ('cflags', test_cflags + ['-I' + os.path.join(gtest_src_dir, 'googletest') ]),
+ ]
+ # Do not use cxx() directly to ensure the object file is under $builddir.
+ objs += n.build(built('gtest_all' + objext), 'cxx', gtest_all_cc, variables=gtest_all_variables)
+
+ ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
+ variables=[('libs', libs)])
+ n.newline()
+ all_targets += ninja_test
+
n.comment('Ancillary executables.')
if platform.is_aix() and '-maix64' not in ldflags:

View File

@ -0,0 +1,24 @@
--- a/configure.py
+++ b/configure.py
@@ -198,6 +198,8 @@ parser = OptionParser()
profilers = ['gmon', 'pprof']
parser.add_option('--bootstrap', action='store_true',
help='bootstrap a ninja binary from nothing')
+parser.add_option('--no-rebuild', action='store_true',
+ help='let user execute ninja after build.ninja generation')
parser.add_option('--verbose', action='store_true',
help='enable verbose build')
parser.add_option('--platform',
@@ -756,7 +758,11 @@ n.build('all', 'phony', all_targets)
n.close()
print('wrote %s.' % BUILD_FILENAME)
-if options.bootstrap:
+if options.bootstrap and options.no_rebuild:
+ print('bootstrap complete. execute ninja in this directory...')
+ print(os.getcwd())
+
+elif options.bootstrap:
print('bootstrap complete. rebuilding...')
rebuild_args = []

View File

@ -18,22 +18,9 @@ Documentation for GNU make jobserver
http://make.mad-scientist.net/papers/jobserver-implementation/
Fixes https://github.com/ninja-build/ninja/issues/1139
---
configure.py | 2 +
src/build.cc | 63 ++++++++----
src/build.h | 3 +
src/tokenpool-gnu-make.cc | 211 ++++++++++++++++++++++++++++++++++++++
src/tokenpool-none.cc | 27 +++++
src/tokenpool.h | 26 +++++
6 files changed, 310 insertions(+), 22 deletions(-)
create mode 100644 src/tokenpool-gnu-make.cc
create mode 100644 src/tokenpool-none.cc
create mode 100644 src/tokenpool.h
--- a/configure.py
+++ b/configure.py
@@ -517,11 +517,13 @@ for name in ['build',
@@ -543,11 +543,13 @@ for name in ['build',
'state',
'status',
'string_piece_util',
@ -47,7 +34,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
'includes_normalize-win32',
'msvc_helper-win32',
'msvc_helper_main-win32']:
@@ -530,7 +532,9 @@ if platform.is_windows():
@@ -556,7 +558,9 @@ if platform.is_windows():
objs += cxx('minidump-win32', variables=cxxvariables)
objs += cc('getopt')
else:
@ -58,17 +45,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
if platform.is_aix():
objs += cc('getopt')
if platform.is_msvc():
@@ -588,6 +592,7 @@ for name in ['build_log_test',
'string_piece_util_test',
'subprocess_test',
'test',
+ 'tokenpool_test',
'util_test']:
objs += cxx(name, variables=cxxvariables)
if platform.is_windows():
@@ -639,6 +643,7 @@ if gtest_src_dir:
'string_piece_util_test',
'subprocess_test',
'test',
+ 'tokenpool_test',
'util_test',
]
if platform.is_windows():
--- a/src/build.cc
+++ b/src/build.cc
@@ -35,6 +35,7 @@
@@ -39,6 +39,7 @@
#include "state.h"
#include "status.h"
#include "subprocess.h"
@ -76,10 +63,12 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
#include "util.h"
using namespace std;
@@ -47,8 +48,9 @@ struct DryRunCommandRunner : public Comm
@@ -50,24 +51,29 @@ struct DryRunCommandRunner : public Comm
virtual ~DryRunCommandRunner() {}
// Overridden from CommandRunner:
virtual bool CanRunMore() const;
- virtual size_t CanRunMore() const;
+ virtual size_t CanRunMore();
+ virtual bool AcquireToken();
virtual bool StartCommand(Edge* edge);
- virtual bool WaitForCommand(Result* result);
@ -87,8 +76,11 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
private:
queue<Edge*> finished_;
@@ -58,12 +60,16 @@ bool DryRunCommandRunner::CanRunMore() c
return true;
};
-size_t DryRunCommandRunner::CanRunMore() const {
+size_t DryRunCommandRunner::CanRunMore() {
return SIZE_MAX;
}
+bool DryRunCommandRunner::AcquireToken() {
@ -105,24 +97,25 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
if (finished_.empty())
return false;
@@ -149,7 +155,7 @@ void Plan::EdgeWanted(const Edge* edge)
@@ -160,7 +166,7 @@ void Plan::EdgeWanted(const Edge* edge)
}
Edge* Plan::FindWork() {
- if (ready_.empty())
+ if (!more_ready())
return NULL;
EdgeSet::iterator e = ready_.begin();
Edge* edge = *e;
@@ -448,19 +454,39 @@ void Plan::Dump() const {
Edge* work = ready_.top();
@@ -595,19 +601,39 @@ void Plan::Dump() const {
}
struct RealCommandRunner : public CommandRunner {
- explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
- virtual ~RealCommandRunner() {}
- virtual size_t CanRunMore() const;
+ explicit RealCommandRunner(const BuildConfig& config);
+ virtual ~RealCommandRunner();
virtual bool CanRunMore() const;
+ virtual size_t CanRunMore();
+ virtual bool AcquireToken();
virtual bool StartCommand(Edge* edge);
- virtual bool WaitForCommand(Result* result);
@ -157,7 +150,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
vector<Edge*> RealCommandRunner::GetActiveEdges() {
vector<Edge*> edges;
for (map<const Subprocess*, Edge*>::iterator e = subproc_to_edge_.begin();
@@ -471,14 +497,23 @@ vector<Edge*> RealCommandRunner::GetActi
@@ -618,9 +644,11 @@ vector<Edge*> RealCommandRunner::GetActi
void RealCommandRunner::Abort() {
subprocs_.Clear();
@ -165,28 +158,35 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+ tokens_->Clear();
}
bool RealCommandRunner::CanRunMore() const {
- size_t subproc_number =
- subprocs_.running_.size() + subprocs_.finished_.size();
- return (int)subproc_number < config_.parallelism
- && ((subprocs_.running_.empty() || config_.max_load_average <= 0.0f)
- || GetLoadAverage() < config_.max_load_average);
+ 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() ||
+ (max_load_average_ <= 0.0f ||
+ GetLoadAverage() < max_load_average_));
+}
-size_t RealCommandRunner::CanRunMore() const {
+size_t RealCommandRunner::CanRunMore() {
size_t subproc_number =
subprocs_.running_.size() + subprocs_.finished_.size();
@@ -635,6 +663,13 @@ size_t RealCommandRunner::CanRunMore() c
if (capacity < 0)
capacity = 0;
+ if (tokens_) {
+ if (AcquireToken())
+ return SIZE_MAX;
+ else
+ capacity = 0;
+ }
+
+bool RealCommandRunner::AcquireToken() {
+ return (!tokens_ || tokens_->Acquire());
if (capacity == 0 && subprocs_.running_.empty())
// Ensure that we make progress.
capacity = 1;
@@ -642,24 +677,42 @@ size_t RealCommandRunner::CanRunMore() c
return capacity;
}
+bool RealCommandRunner::AcquireToken() {
+ return (!tokens_ || tokens_->Acquire());
+}
+
bool RealCommandRunner::StartCommand(Edge* edge) {
@@ -486,19 +521,33 @@ bool RealCommandRunner::StartCommand(Edg
string command = edge->EvaluateCommand();
Subprocess* subproc = subprocs_.Add(command, edge->use_console());
if (!subproc)
return false;
@ -223,61 +223,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
result->status = subproc->Finish();
result->output = subproc->GetOutput();
@@ -620,38 +669,43 @@ bool Builder::Build(string* err) {
// command runner.
@@ -790,7 +843,8 @@ bool Builder::Build(string* err) {
// Second, we attempt to wait for / reap the next finished command.
while (plan_.more_to_do()) {
- // See if we can start any more commands.
- if (failures_allowed && command_runner_->CanRunMore()) {
- if (Edge* edge = plan_.FindWork()) {
- if (edge->GetBindingBool("generator")) {
+ // See if we can start any more commands...
+ bool can_run_more =
+ failures_allowed &&
+ plan_.more_ready() &&
+ command_runner_->CanRunMore();
+
+ // ... but we also need a token to do that.
+ if (can_run_more && command_runner_->AcquireToken()) {
+ Edge* edge = plan_.FindWork();
+ if (edge->GetBindingBool("generator")) {
scan_.build_log()->Close();
}
- if (!StartEdge(edge, err)) {
+ if (!StartEdge(edge, err)) {
+ Cleanup();
+ status_->BuildFinished();
+ return false;
+ }
+
+ if (edge->is_phony()) {
+ if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err)) {
Cleanup();
status_->BuildFinished();
return false;
}
-
- if (edge->is_phony()) {
- if (!plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, err)) {
- Cleanup();
- status_->BuildFinished();
- return false;
- }
- } else {
- ++pending_commands;
- }
-
- // We made some progress; go back to the main loop.
- continue;
+ } else {
+ ++pending_commands;
}
+
+ // We made some progress; go back to the main loop.
+ continue;
}
// See if we can start any more commands.
- if (failures_allowed) {
+ bool can_run_more = failures_allowed && plan_.more_ready();
+ if (can_run_more) {
size_t capacity = command_runner_->CanRunMore();
while (capacity > 0) {
Edge* edge = plan_.FindWork();
@@ -833,7 +887,7 @@ bool Builder::Build(string* err) {
// See if we can reap any finished commands.
if (pending_commands) {
CommandRunner::Result result;
@ -286,7 +242,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
result.status == ExitInterrupted) {
Cleanup();
status_->BuildFinished();
@@ -659,6 +713,10 @@ bool Builder::Build(string* err) {
@@ -841,6 +895,10 @@ bool Builder::Build(string* err) {
return false;
}
@ -299,7 +255,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
Cleanup();
--- a/src/build.h
+++ b/src/build.h
@@ -52,6 +52,9 @@ struct Plan {
@@ -51,6 +51,9 @@ struct Plan {
/// Returns true if there's more work to be done.
bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
@ -309,15 +265,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
/// Dumps the current state of the plan.
void Dump() const;
@@ -136,6 +139,7 @@ private:
@@ -145,7 +148,8 @@ private:
/// RealCommandRunner is an implementation that actually runs commands.
struct CommandRunner {
virtual ~CommandRunner() {}
virtual bool CanRunMore() const = 0;
- virtual size_t CanRunMore() const = 0;
+ virtual size_t CanRunMore() = 0;
+ virtual bool AcquireToken() = 0;
virtual bool StartCommand(Edge* edge) = 0;
/// The result of waiting for a command.
@@ -147,7 +151,9 @@ struct CommandRunner {
@@ -157,7 +161,9 @@ struct CommandRunner {
bool success() const { return status == ExitSuccess; }
};
/// Wait for a command to complete, or return false if interrupted.
@ -328,7 +286,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
virtual std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
virtual void Abort() {}
@@ -155,7 +161,8 @@ struct CommandRunner {
@@ -165,7 +171,8 @@ struct CommandRunner {
/// Options (e.g. verbosity, parallelism) passed to a build.
struct BuildConfig {
@ -338,7 +296,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
failures_allowed(1), max_load_average(-0.0f) {}
enum Verbosity {
@@ -167,6 +174,7 @@ struct BuildConfig {
@@ -177,6 +184,7 @@ struct BuildConfig {
Verbosity verbosity;
bool dry_run;
int parallelism;
@ -509,13 +467,15 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
#include <assert.h>
+#include <stdarg.h>
#include <climits>
#include <stdint.h>
#include "build_log.h"
#include "deps_log.h"
@@ -474,8 +475,9 @@ struct FakeCommandRunner : public Comman
@@ -521,9 +522,10 @@ struct FakeCommandRunner : public Comman
max_active_edges_(1), fs_(fs) {}
// CommandRunner impl
virtual bool CanRunMore() const;
- virtual size_t CanRunMore() const;
+ virtual size_t CanRunMore();
+ virtual bool AcquireToken();
virtual bool StartCommand(Edge* edge);
- virtual bool WaitForCommand(Result* result);
@ -523,8 +483,16 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
virtual vector<Edge*> GetActiveEdges();
virtual void Abort();
@@ -578,6 +580,10 @@ bool FakeCommandRunner::CanRunMore() con
return active_edges_.size() < max_active_edges_;
@@ -622,13 +624,17 @@ void BuildTest::RebuildTarget(const stri
builder.command_runner_.release();
}
-size_t FakeCommandRunner::CanRunMore() const {
+size_t FakeCommandRunner::CanRunMore() {
if (active_edges_.size() < max_active_edges_)
return SIZE_MAX;
return 0;
}
+bool FakeCommandRunner::AcquireToken() {
@ -534,7 +502,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
bool FakeCommandRunner::StartCommand(Edge* edge) {
assert(active_edges_.size() < max_active_edges_);
assert(find(active_edges_.begin(), active_edges_.end(), edge)
@@ -649,7 +655,7 @@ bool FakeCommandRunner::StartCommand(Edg
@@ -720,7 +726,7 @@ bool FakeCommandRunner::StartCommand(Edg
return true;
}
@ -543,7 +511,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
if (active_edges_.empty())
return false;
@@ -3985,3 +3991,356 @@ TEST_F(BuildTest, ValidationWithCircular
@@ -4380,3 +4386,355 @@ TEST_F(BuildTest, ValidationWithCircular
EXPECT_FALSE(builder_.AddTarget("out", &err));
EXPECT_EQ("dependency cycle: validate -> validate_in -> validate", err);
}
@ -557,7 +525,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+ explicit FakeTokenCommandRunner() {}
+
+ // CommandRunner impl
+ virtual bool CanRunMore() const;
+ virtual bool CanRunMore();
+ virtual bool AcquireToken();
+ virtual bool StartCommand(Edge* edge);
+ virtual bool WaitForCommand(Result* result, bool more_ready);
@ -572,7 +540,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+ vector<bool> wait_for_command_;
+};
+
+bool FakeTokenCommandRunner::CanRunMore() const {
+bool FakeTokenCommandRunner::CanRunMore() {
+ if (can_run_more_.size() == 0) {
+ EXPECT_FALSE("unexpected call to CommandRunner::CanRunMore()");
+ return false;
@ -580,9 +548,8 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+
+ bool result = can_run_more_[0];
+
+ // Unfortunately CanRunMore() isn't "const" for tests
+ const_cast<FakeTokenCommandRunner*>(this)->can_run_more_.erase(
+ const_cast<FakeTokenCommandRunner*>(this)->can_run_more_.begin()
+ can_run_more_.erase(
+ can_run_more_.begin()
+ );
+
+ return result;
@ -1345,7 +1312,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+}
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -1447,6 +1447,7 @@ int ReadFlags(int* argc, char*** argv,
@@ -1466,6 +1466,7 @@ int ReadFlags(int* argc, char*** argv,
// We want to run N jobs in parallel. For N = 0, INT_MAX
// is close enough to infinite for most sane builds.
config->parallelism = value > 0 ? value : INT_MAX;
@ -2139,7 +2106,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
+};
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -112,6 +112,7 @@ add_library(libninja OBJECT
@@ -142,6 +142,7 @@ add_library(libninja OBJECT
src/state.cc
src/status.cc
src/string_piece_util.cc
@ -2147,22 +2114,26 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
src/util.cc
src/version.cc
)
@@ -123,9 +124,14 @@ if(WIN32)
@@ -153,13 +154,17 @@ if(WIN32)
src/msvc_helper_main-win32.cc
src/getopt.c
src/minidump-win32.cc
+ src/tokenpool-gnu-make-win32.cc
)
# Build getopt.c, which can be compiled as either C or C++, as C++
# so that build environments which lack a C compiler, but have a C++
# compiler may build ninja.
set_source_files_properties(src/getopt.c PROPERTIES LANGUAGE CXX)
else()
target_sources(libninja PRIVATE src/subprocess-posix.cc)
- target_sources(libninja PRIVATE src/subprocess-posix.cc)
+ target_sources(libninja PRIVATE
+ src/subprocess-posix.cc
+ src/tokenpool-gnu-make-posix.cc
+ )
if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
target_sources(libninja PRIVATE src/getopt.c)
endif()
@@ -204,6 +210,7 @@ if(BUILD_TESTING)
# Build getopt.c, which can be compiled as either C or C++, as C++
@@ -286,6 +291,7 @@ if(BUILD_TESTING)
src/string_piece_util_test.cc
src/subprocess_test.cc
src/test.cc