Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
8cdf691d8c
@ -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;
|
||||
@ -75,8 +75,8 @@ platform_do_upgrade() {
|
||||
;;
|
||||
iptime,nas1dual)
|
||||
PART_NAME=firmware
|
||||
default_do_upgrade "$1"
|
||||
;;
|
||||
|
||||
linksys,wrt1200ac|\
|
||||
linksys,wrt1900ac-v1|\
|
||||
linksys,wrt1900ac-v2|\
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
153
tools/ninja/patches/001-backport-gtest.patch
Normal file
153
tools/ninja/patches/001-backport-gtest.patch
Normal 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:
|
||||
24
tools/ninja/patches/010-bootstrap-configure-only.patch
Normal file
24
tools/ninja/patches/010-bootstrap-configure-only.patch
Normal 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 = []
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user