aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp30
-rw-r--r--src/test/setup_common.cpp7
-rw-r--r--src/validation.cpp6
-rw-r--r--src/validation.h9
4 files changed, 32 insertions, 20 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 1a99ca9abc..c8725f2596 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1061,15 +1061,6 @@ bool AppInitParameterInteraction()
incrementalRelayFee = CFeeRate(n);
}
- // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
- nScriptCheckThreads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
- if (nScriptCheckThreads <= 0)
- nScriptCheckThreads += GetNumCores();
- if (nScriptCheckThreads <= 1)
- nScriptCheckThreads = 0;
- else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
- nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
-
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
int64_t nPruneArg = gArgs.GetArg("-prune", 0);
if (nPruneArg < 0) {
@@ -1256,10 +1247,25 @@ bool AppInitMain(NodeContext& node)
InitSignatureCache();
InitScriptExecutionCache();
- LogPrintf("Script verification uses %d additional threads\n", std::max(nScriptCheckThreads - 1, 0));
- if (nScriptCheckThreads) {
- for (int i=0; i<nScriptCheckThreads-1; i++)
+ int script_threads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
+ if (script_threads <= 0) {
+ // -par=0 means autodetect (number of cores - 1 script threads)
+ // -par=-n means "leave n cores free" (number of cores - n - 1 script threads)
+ script_threads += GetNumCores();
+ }
+
+ // Subtract 1 because the main thread counts towards the par threads
+ script_threads = std::max(script_threads - 1, 0);
+
+ // Number of script-checking threads <= MAX_SCRIPTCHECK_THREADS
+ script_threads = std::min(script_threads, MAX_SCRIPTCHECK_THREADS);
+
+ LogPrintf("Script verification uses %d additional threads\n", script_threads);
+ if (script_threads >= 1) {
+ g_parallel_script_checks = true;
+ for (int i = 0; i < script_threads; ++i) {
threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
+ }
}
// Start the lightweight task scheduler thread
diff --git a/src/test/setup_common.cpp b/src/test/setup_common.cpp
index 3425bd59c1..5e7da84dfb 100644
--- a/src/test/setup_common.cpp
+++ b/src/test/setup_common.cpp
@@ -102,9 +102,12 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", FormatStateMessage(state)));
}
- nScriptCheckThreads = 3;
- for (int i = 0; i < nScriptCheckThreads - 1; i++)
+ // Start script-checking threads. Set g_parallel_script_checks to true so they are used.
+ constexpr int script_check_threads = 2;
+ for (int i = 0; i < script_check_threads; ++i) {
threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
+ }
+ g_parallel_script_checks = true;
m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
diff --git a/src/validation.cpp b/src/validation.cpp
index ca6d2176b3..df01b3abcf 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -107,7 +107,7 @@ CBlockIndex *pindexBestHeader = nullptr;
Mutex g_best_block_mutex;
std::condition_variable g_best_block_cv;
uint256 g_best_block;
-int nScriptCheckThreads = 0;
+bool g_parallel_script_checks{false};
std::atomic_bool fImporting(false);
std::atomic_bool fReindex(false);
bool fHavePruned = false;
@@ -2069,7 +2069,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
CBlockUndo blockundo;
- CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr);
+ CCheckQueueControl<CScriptCheck> control(fScriptChecks && g_parallel_script_checks ? &scriptcheckqueue : nullptr);
std::vector<int> prevheights;
CAmount nFees = 0;
@@ -2130,7 +2130,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
std::vector<CScriptCheck> vChecks;
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
TxValidationState tx_state;
- if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : nullptr)) {
+ if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
// Any transaction validation failure in ConnectBlock is a block consensus failure
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
diff --git a/src/validation.h b/src/validation.h
index 7f9582adfd..fd846e9090 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -76,8 +76,8 @@ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
-/** Maximum number of script-checking threads allowed */
-static const int MAX_SCRIPTCHECK_THREADS = 16;
+/** Maximum number of dedicated script-checking threads allowed */
+static const int MAX_SCRIPTCHECK_THREADS = 15;
/** -par default (number of script-checking threads, 0 = auto) */
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
/** Number of blocks that can be requested at any given time from a single peer. */
@@ -146,7 +146,10 @@ extern std::condition_variable g_best_block_cv;
extern uint256 g_best_block;
extern std::atomic_bool fImporting;
extern std::atomic_bool fReindex;
-extern int nScriptCheckThreads;
+/** Whether there are dedicated script-checking threads running.
+ * False indicates all script checking is done on the main threadMessageHandler thread.
+ */
+extern bool g_parallel_script_checks;
extern bool fRequireStandard;
extern bool fCheckBlockIndex;
extern bool fCheckpointsEnabled;