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)
|
iptime,nas1dual)
|
||||||
PART_NAME=firmware
|
PART_NAME=firmware
|
||||||
|
default_do_upgrade "$1"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
linksys,wrt1200ac|\
|
linksys,wrt1200ac|\
|
||||||
linksys,wrt1900ac-v1|\
|
linksys,wrt1900ac-v1|\
|
||||||
linksys,wrt1900ac-v2|\
|
linksys,wrt1900ac-v2|\
|
||||||
|
|||||||
@ -8,7 +8,7 @@ ARCH:=powerpc64
|
|||||||
BOARD:=qoriq
|
BOARD:=qoriq
|
||||||
BOARDNAME:=NXP QorIQ (PowerPC)
|
BOARDNAME:=NXP QorIQ (PowerPC)
|
||||||
CPU_TYPE:=e5500
|
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
|
SUBTARGETS:=generic
|
||||||
|
|
||||||
KERNEL_PATCHVER:=6.6
|
KERNEL_PATCHVER:=6.6
|
||||||
|
|||||||
@ -103,6 +103,7 @@ CONFIG_DMA_ENGINE=y
|
|||||||
CONFIG_DMA_OF=y
|
CONFIG_DMA_OF=y
|
||||||
CONFIG_DMA_OPS=y
|
CONFIG_DMA_OPS=y
|
||||||
CONFIG_DMA_OPS_BYPASS=y
|
CONFIG_DMA_OPS_BYPASS=y
|
||||||
|
# CONFIG_DRM_OFDRM is not set
|
||||||
CONFIG_DTC=y
|
CONFIG_DTC=y
|
||||||
CONFIG_DUMMY_CONSOLE=y
|
CONFIG_DUMMY_CONSOLE=y
|
||||||
# CONFIG_E5500_CPU is not set
|
# CONFIG_E5500_CPU is not set
|
||||||
|
|||||||
@ -1,38 +1,35 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=ninja
|
PKG_NAME:=ninja
|
||||||
PKG_VERSION:=1.11.1
|
PKG_VERSION:=1.12.1
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://codeload.github.com/ninja-build/ninja/tar.gz/v$(PKG_VERSION)?
|
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
|
include $(INCLUDE_DIR)/host-build.mk
|
||||||
|
|
||||||
CONFIGURE_ARGS:=
|
|
||||||
ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
|
|
||||||
CONFIGURE_ARGS+=--verbose
|
|
||||||
endif
|
|
||||||
|
|
||||||
define Host/Configure
|
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
|
endef
|
||||||
|
|
||||||
define Host/Compile
|
define Host/Compile
|
||||||
cd $(HOST_BUILD_DIR) && \
|
+$(NINJA) -C $(HOST_BUILD_DIR)
|
||||||
CXX="$(HOSTCXX_NOCACHE)" \
|
|
||||||
CXXFLAGS="$(HOST_CXXFLAGS) $(HOST_CPPFLAGS)" \
|
|
||||||
LDFLAGS="$(HOST_LDFLAGS)" \
|
|
||||||
$(STAGING_DIR_HOST)/bin/$(PYTHON) configure.py --bootstrap $(CONFIGURE_ARGS)
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Host/Install
|
define Host/Install
|
||||||
$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
|
|
||||||
$(INSTALL_BIN) $(HOST_BUILD_DIR)/ninja $(STAGING_DIR_HOST)/bin/
|
$(INSTALL_BIN) $(HOST_BUILD_DIR)/ninja $(STAGING_DIR_HOST)/bin/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Host/Clean
|
define Host/Clean
|
||||||
$(call Host/Clean/Default)
|
|
||||||
rm -f $(STAGING_DIR_HOST)/bin/ninja
|
rm -f $(STAGING_DIR_HOST)/bin/ninja
|
||||||
endef
|
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/
|
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
|
--- a/configure.py
|
||||||
+++ b/configure.py
|
+++ b/configure.py
|
||||||
@@ -517,11 +517,13 @@ for name in ['build',
|
@@ -543,11 +543,13 @@ for name in ['build',
|
||||||
'state',
|
'state',
|
||||||
'status',
|
'status',
|
||||||
'string_piece_util',
|
'string_piece_util',
|
||||||
@ -47,7 +34,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
'includes_normalize-win32',
|
'includes_normalize-win32',
|
||||||
'msvc_helper-win32',
|
'msvc_helper-win32',
|
||||||
'msvc_helper_main-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 += cxx('minidump-win32', variables=cxxvariables)
|
||||||
objs += cc('getopt')
|
objs += cc('getopt')
|
||||||
else:
|
else:
|
||||||
@ -58,17 +45,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
if platform.is_aix():
|
if platform.is_aix():
|
||||||
objs += cc('getopt')
|
objs += cc('getopt')
|
||||||
if platform.is_msvc():
|
if platform.is_msvc():
|
||||||
@@ -588,6 +592,7 @@ for name in ['build_log_test',
|
@@ -639,6 +643,7 @@ if gtest_src_dir:
|
||||||
'string_piece_util_test',
|
'string_piece_util_test',
|
||||||
'subprocess_test',
|
'subprocess_test',
|
||||||
'test',
|
'test',
|
||||||
+ 'tokenpool_test',
|
+ 'tokenpool_test',
|
||||||
'util_test']:
|
'util_test',
|
||||||
objs += cxx(name, variables=cxxvariables)
|
]
|
||||||
if platform.is_windows():
|
if platform.is_windows():
|
||||||
--- a/src/build.cc
|
--- a/src/build.cc
|
||||||
+++ b/src/build.cc
|
+++ b/src/build.cc
|
||||||
@@ -35,6 +35,7 @@
|
@@ -39,6 +39,7 @@
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "subprocess.h"
|
#include "subprocess.h"
|
||||||
@ -76,10 +63,12 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -47,8 +48,9 @@ struct DryRunCommandRunner : public Comm
|
@@ -50,24 +51,29 @@ struct DryRunCommandRunner : public Comm
|
||||||
|
virtual ~DryRunCommandRunner() {}
|
||||||
|
|
||||||
// Overridden from CommandRunner:
|
// Overridden from CommandRunner:
|
||||||
virtual bool CanRunMore() const;
|
- virtual size_t CanRunMore() const;
|
||||||
|
+ virtual size_t CanRunMore();
|
||||||
+ virtual bool AcquireToken();
|
+ virtual bool AcquireToken();
|
||||||
virtual bool StartCommand(Edge* edge);
|
virtual bool StartCommand(Edge* edge);
|
||||||
- virtual bool WaitForCommand(Result* result);
|
- virtual bool WaitForCommand(Result* result);
|
||||||
@ -87,8 +76,11 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
queue<Edge*> finished_;
|
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() {
|
+bool DryRunCommandRunner::AcquireToken() {
|
||||||
@ -105,24 +97,25 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
if (finished_.empty())
|
if (finished_.empty())
|
||||||
return false;
|
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() {
|
Edge* Plan::FindWork() {
|
||||||
- if (ready_.empty())
|
- if (ready_.empty())
|
||||||
+ if (!more_ready())
|
+ if (!more_ready())
|
||||||
return NULL;
|
return NULL;
|
||||||
EdgeSet::iterator e = ready_.begin();
|
|
||||||
Edge* edge = *e;
|
Edge* work = ready_.top();
|
||||||
@@ -448,19 +454,39 @@ void Plan::Dump() const {
|
@@ -595,19 +601,39 @@ void Plan::Dump() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RealCommandRunner : public CommandRunner {
|
struct RealCommandRunner : public CommandRunner {
|
||||||
- explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
|
- explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
|
||||||
- virtual ~RealCommandRunner() {}
|
- virtual ~RealCommandRunner() {}
|
||||||
|
- virtual size_t CanRunMore() const;
|
||||||
+ explicit RealCommandRunner(const BuildConfig& config);
|
+ explicit RealCommandRunner(const BuildConfig& config);
|
||||||
+ virtual ~RealCommandRunner();
|
+ virtual ~RealCommandRunner();
|
||||||
virtual bool CanRunMore() const;
|
+ virtual size_t CanRunMore();
|
||||||
+ virtual bool AcquireToken();
|
+ virtual bool AcquireToken();
|
||||||
virtual bool StartCommand(Edge* edge);
|
virtual bool StartCommand(Edge* edge);
|
||||||
- virtual bool WaitForCommand(Result* result);
|
- virtual bool WaitForCommand(Result* result);
|
||||||
@ -157,7 +150,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
vector<Edge*> RealCommandRunner::GetActiveEdges() {
|
vector<Edge*> RealCommandRunner::GetActiveEdges() {
|
||||||
vector<Edge*> edges;
|
vector<Edge*> edges;
|
||||||
for (map<const Subprocess*, Edge*>::iterator e = subproc_to_edge_.begin();
|
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() {
|
void RealCommandRunner::Abort() {
|
||||||
subprocs_.Clear();
|
subprocs_.Clear();
|
||||||
@ -165,28 +158,35 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
+ tokens_->Clear();
|
+ tokens_->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealCommandRunner::CanRunMore() const {
|
-size_t RealCommandRunner::CanRunMore() const {
|
||||||
- size_t subproc_number =
|
+size_t RealCommandRunner::CanRunMore() {
|
||||||
- subprocs_.running_.size() + subprocs_.finished_.size();
|
size_t subproc_number =
|
||||||
- return (int)subproc_number < config_.parallelism
|
subprocs_.running_.size() + subprocs_.finished_.size();
|
||||||
- && ((subprocs_.running_.empty() || config_.max_load_average <= 0.0f)
|
|
||||||
- || GetLoadAverage() < config_.max_load_average);
|
@@ -635,6 +663,13 @@ size_t RealCommandRunner::CanRunMore() c
|
||||||
+ bool parallelism_limit_not_reached =
|
if (capacity < 0)
|
||||||
+ tokens_ || // ignore config_.parallelism
|
capacity = 0;
|
||||||
+ ((int) (subprocs_.running_.size() +
|
|
||||||
+ subprocs_.finished_.size()) < config_.parallelism);
|
+ if (tokens_) {
|
||||||
+ return parallelism_limit_not_reached
|
+ if (AcquireToken())
|
||||||
+ && (subprocs_.running_.empty() ||
|
+ return SIZE_MAX;
|
||||||
+ (max_load_average_ <= 0.0f ||
|
+ else
|
||||||
+ GetLoadAverage() < max_load_average_));
|
+ capacity = 0;
|
||||||
+}
|
+ }
|
||||||
+
|
+
|
||||||
+bool RealCommandRunner::AcquireToken() {
|
if (capacity == 0 && subprocs_.running_.empty())
|
||||||
+ return (!tokens_ || tokens_->Acquire());
|
// 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) {
|
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());
|
Subprocess* subproc = subprocs_.Add(command, edge->use_console());
|
||||||
if (!subproc)
|
if (!subproc)
|
||||||
return false;
|
return false;
|
||||||
@ -223,61 +223,17 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
result->status = subproc->Finish();
|
result->status = subproc->Finish();
|
||||||
result->output = subproc->GetOutput();
|
result->output = subproc->GetOutput();
|
||||||
|
|
||||||
@@ -620,38 +669,43 @@ bool Builder::Build(string* err) {
|
@@ -790,7 +843,8 @@ bool Builder::Build(string* err) {
|
||||||
// command runner.
|
|
||||||
// Second, we attempt to wait for / reap the next finished command.
|
// Second, we attempt to wait for / reap the next finished command.
|
||||||
while (plan_.more_to_do()) {
|
while (plan_.more_to_do()) {
|
||||||
- // See if we can start any more commands.
|
// See if we can start any more commands.
|
||||||
- if (failures_allowed && command_runner_->CanRunMore()) {
|
- if (failures_allowed) {
|
||||||
- if (Edge* edge = plan_.FindWork()) {
|
+ bool can_run_more = failures_allowed && plan_.more_ready();
|
||||||
- if (edge->GetBindingBool("generator")) {
|
+ if (can_run_more) {
|
||||||
+ // See if we can start any more commands...
|
size_t capacity = command_runner_->CanRunMore();
|
||||||
+ bool can_run_more =
|
while (capacity > 0) {
|
||||||
+ failures_allowed &&
|
Edge* edge = plan_.FindWork();
|
||||||
+ plan_.more_ready() &&
|
@@ -833,7 +887,7 @@ bool Builder::Build(string* err) {
|
||||||
+ 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 reap any finished commands.
|
// See if we can reap any finished commands.
|
||||||
if (pending_commands) {
|
if (pending_commands) {
|
||||||
CommandRunner::Result result;
|
CommandRunner::Result result;
|
||||||
@ -286,7 +242,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
result.status == ExitInterrupted) {
|
result.status == ExitInterrupted) {
|
||||||
Cleanup();
|
Cleanup();
|
||||||
status_->BuildFinished();
|
status_->BuildFinished();
|
||||||
@@ -659,6 +713,10 @@ bool Builder::Build(string* err) {
|
@@ -841,6 +895,10 @@ bool Builder::Build(string* err) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +255,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
Cleanup();
|
Cleanup();
|
||||||
--- a/src/build.h
|
--- a/src/build.h
|
||||||
+++ b/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.
|
/// Returns true if there's more work to be done.
|
||||||
bool more_to_do() const { return wanted_edges_ > 0 && command_edges_ > 0; }
|
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.
|
/// Dumps the current state of the plan.
|
||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
|
||||||
@@ -136,6 +139,7 @@ private:
|
@@ -145,7 +148,8 @@ private:
|
||||||
|
/// RealCommandRunner is an implementation that actually runs commands.
|
||||||
struct CommandRunner {
|
struct CommandRunner {
|
||||||
virtual ~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 AcquireToken() = 0;
|
||||||
virtual bool StartCommand(Edge* edge) = 0;
|
virtual bool StartCommand(Edge* edge) = 0;
|
||||||
|
|
||||||
/// The result of waiting for a command.
|
/// 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; }
|
bool success() const { return status == ExitSuccess; }
|
||||||
};
|
};
|
||||||
/// Wait for a command to complete, or return false if interrupted.
|
/// 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 std::vector<Edge*> GetActiveEdges() { return std::vector<Edge*>(); }
|
||||||
virtual void Abort() {}
|
virtual void Abort() {}
|
||||||
@@ -155,7 +161,8 @@ struct CommandRunner {
|
@@ -165,7 +171,8 @@ struct CommandRunner {
|
||||||
|
|
||||||
/// Options (e.g. verbosity, parallelism) passed to a build.
|
/// Options (e.g. verbosity, parallelism) passed to a build.
|
||||||
struct BuildConfig {
|
struct BuildConfig {
|
||||||
@ -338,7 +296,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
failures_allowed(1), max_load_average(-0.0f) {}
|
failures_allowed(1), max_load_average(-0.0f) {}
|
||||||
|
|
||||||
enum Verbosity {
|
enum Verbosity {
|
||||||
@@ -167,6 +174,7 @@ struct BuildConfig {
|
@@ -177,6 +184,7 @@ struct BuildConfig {
|
||||||
Verbosity verbosity;
|
Verbosity verbosity;
|
||||||
bool dry_run;
|
bool dry_run;
|
||||||
int parallelism;
|
int parallelism;
|
||||||
@ -509,13 +467,15 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
+#include <stdarg.h>
|
+#include <stdarg.h>
|
||||||
|
#include <climits>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "build_log.h"
|
@@ -521,9 +522,10 @@ struct FakeCommandRunner : public Comman
|
||||||
#include "deps_log.h"
|
max_active_edges_(1), fs_(fs) {}
|
||||||
@@ -474,8 +475,9 @@ struct FakeCommandRunner : public Comman
|
|
||||||
|
|
||||||
// CommandRunner impl
|
// CommandRunner impl
|
||||||
virtual bool CanRunMore() const;
|
- virtual size_t CanRunMore() const;
|
||||||
|
+ virtual size_t CanRunMore();
|
||||||
+ virtual bool AcquireToken();
|
+ virtual bool AcquireToken();
|
||||||
virtual bool StartCommand(Edge* edge);
|
virtual bool StartCommand(Edge* edge);
|
||||||
- virtual bool WaitForCommand(Result* result);
|
- virtual bool WaitForCommand(Result* result);
|
||||||
@ -523,8 +483,16 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
virtual vector<Edge*> GetActiveEdges();
|
virtual vector<Edge*> GetActiveEdges();
|
||||||
virtual void Abort();
|
virtual void Abort();
|
||||||
|
|
||||||
@@ -578,6 +580,10 @@ bool FakeCommandRunner::CanRunMore() con
|
@@ -622,13 +624,17 @@ void BuildTest::RebuildTarget(const stri
|
||||||
return active_edges_.size() < max_active_edges_;
|
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() {
|
+bool FakeCommandRunner::AcquireToken() {
|
||||||
@ -534,7 +502,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
bool FakeCommandRunner::StartCommand(Edge* edge) {
|
bool FakeCommandRunner::StartCommand(Edge* edge) {
|
||||||
assert(active_edges_.size() < max_active_edges_);
|
assert(active_edges_.size() < max_active_edges_);
|
||||||
assert(find(active_edges_.begin(), active_edges_.end(), edge)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,7 +511,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
if (active_edges_.empty())
|
if (active_edges_.empty())
|
||||||
return false;
|
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_FALSE(builder_.AddTarget("out", &err));
|
||||||
EXPECT_EQ("dependency cycle: validate -> validate_in -> validate", 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() {}
|
+ explicit FakeTokenCommandRunner() {}
|
||||||
+
|
+
|
||||||
+ // CommandRunner impl
|
+ // CommandRunner impl
|
||||||
+ virtual bool CanRunMore() const;
|
+ virtual bool CanRunMore();
|
||||||
+ virtual bool AcquireToken();
|
+ virtual bool AcquireToken();
|
||||||
+ virtual bool StartCommand(Edge* edge);
|
+ virtual bool StartCommand(Edge* edge);
|
||||||
+ virtual bool WaitForCommand(Result* result, bool more_ready);
|
+ 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_;
|
+ vector<bool> wait_for_command_;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+bool FakeTokenCommandRunner::CanRunMore() const {
|
+bool FakeTokenCommandRunner::CanRunMore() {
|
||||||
+ if (can_run_more_.size() == 0) {
|
+ if (can_run_more_.size() == 0) {
|
||||||
+ EXPECT_FALSE("unexpected call to CommandRunner::CanRunMore()");
|
+ EXPECT_FALSE("unexpected call to CommandRunner::CanRunMore()");
|
||||||
+ return false;
|
+ return false;
|
||||||
@ -580,9 +548,8 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
+
|
+
|
||||||
+ bool result = can_run_more_[0];
|
+ bool result = can_run_more_[0];
|
||||||
+
|
+
|
||||||
+ // Unfortunately CanRunMore() isn't "const" for tests
|
+ can_run_more_.erase(
|
||||||
+ const_cast<FakeTokenCommandRunner*>(this)->can_run_more_.erase(
|
+ can_run_more_.begin()
|
||||||
+ const_cast<FakeTokenCommandRunner*>(this)->can_run_more_.begin()
|
|
||||||
+ );
|
+ );
|
||||||
+
|
+
|
||||||
+ return result;
|
+ return result;
|
||||||
@ -1345,7 +1312,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
+}
|
+}
|
||||||
--- a/src/ninja.cc
|
--- a/src/ninja.cc
|
||||||
+++ b/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
|
// We want to run N jobs in parallel. For N = 0, INT_MAX
|
||||||
// is close enough to infinite for most sane builds.
|
// is close enough to infinite for most sane builds.
|
||||||
config->parallelism = value > 0 ? value : INT_MAX;
|
config->parallelism = value > 0 ? value : INT_MAX;
|
||||||
@ -2139,7 +2106,7 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
+};
|
+};
|
||||||
--- a/CMakeLists.txt
|
--- a/CMakeLists.txt
|
||||||
+++ b/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/state.cc
|
||||||
src/status.cc
|
src/status.cc
|
||||||
src/string_piece_util.cc
|
src/string_piece_util.cc
|
||||||
@ -2147,22 +2114,26 @@ Fixes https://github.com/ninja-build/ninja/issues/1139
|
|||||||
src/util.cc
|
src/util.cc
|
||||||
src/version.cc
|
src/version.cc
|
||||||
)
|
)
|
||||||
@@ -123,9 +124,14 @@ if(WIN32)
|
@@ -153,13 +154,17 @@ if(WIN32)
|
||||||
src/msvc_helper_main-win32.cc
|
src/msvc_helper_main-win32.cc
|
||||||
src/getopt.c
|
src/getopt.c
|
||||||
src/minidump-win32.cc
|
src/minidump-win32.cc
|
||||||
+ src/tokenpool-gnu-make-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()
|
else()
|
||||||
target_sources(libninja PRIVATE src/subprocess-posix.cc)
|
- target_sources(libninja PRIVATE src/subprocess-posix.cc)
|
||||||
+ target_sources(libninja PRIVATE
|
+ target_sources(libninja PRIVATE
|
||||||
+ src/subprocess-posix.cc
|
+ src/subprocess-posix.cc
|
||||||
+ src/tokenpool-gnu-make-posix.cc
|
+ src/tokenpool-gnu-make-posix.cc
|
||||||
+ )
|
+ )
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
|
if(CMAKE_SYSTEM_NAME STREQUAL "OS400" OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
|
||||||
target_sources(libninja PRIVATE src/getopt.c)
|
target_sources(libninja PRIVATE src/getopt.c)
|
||||||
endif()
|
# Build getopt.c, which can be compiled as either C or C++, as C++
|
||||||
@@ -204,6 +210,7 @@ if(BUILD_TESTING)
|
@@ -286,6 +291,7 @@ if(BUILD_TESTING)
|
||||||
src/string_piece_util_test.cc
|
src/string_piece_util_test.cc
|
||||||
src/subprocess_test.cc
|
src/subprocess_test.cc
|
||||||
src/test.cc
|
src/test.cc
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user