Skip to content

Commit 7d14e35

Browse files
author
MarcoFalke
committed
Merge #17342: refactor: Clean up nScriptCheckThreads
5506ecf [refactor] Replace global int nScriptCheckThreads with bool (John Newbery) d995762 [tests] Don't use TestingSetup in the checkqueue_tests (John Newbery) Pull request description: The meaning of this value is confusing. Refactor it and add comments. ACKs for top commit: sipa: ACK 5506ecf promag: ACK 5506ecf, only change was addressing my nits. laanwj: Code review ACK 5506ecf MarcoFalke: ACK 5506ecf 🥐 Tree-SHA512: 78536727c98d2c23f3c0f3f169131474fef9a4486ae65029011caf06eab30f6f70ff73a65b2fb04a5d969fc1150858d1c6ea4767f04d48c1eea6b829316d0e63
2 parents 46e0e27 + 5506ecf commit 7d14e35

File tree

5 files changed

+39
-29
lines changed

5 files changed

+39
-29
lines changed

src/init.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,15 +1047,6 @@ bool AppInitParameterInteraction()
10471047
incrementalRelayFee = CFeeRate(n);
10481048
}
10491049

1050-
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
1051-
nScriptCheckThreads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
1052-
if (nScriptCheckThreads <= 0)
1053-
nScriptCheckThreads += GetNumCores();
1054-
if (nScriptCheckThreads <= 1)
1055-
nScriptCheckThreads = 0;
1056-
else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
1057-
nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
1058-
10591050
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
10601051
int64_t nPruneArg = gArgs.GetArg("-prune", 0);
10611052
if (nPruneArg < 0) {
@@ -1242,10 +1233,25 @@ bool AppInitMain(NodeContext& node)
12421233
InitSignatureCache();
12431234
InitScriptExecutionCache();
12441235

1245-
LogPrintf("Script verification uses %d additional threads\n", std::max(nScriptCheckThreads - 1, 0));
1246-
if (nScriptCheckThreads) {
1247-
for (int i=0; i<nScriptCheckThreads-1; i++)
1236+
int script_threads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
1237+
if (script_threads <= 0) {
1238+
// -par=0 means autodetect (number of cores - 1 script threads)
1239+
// -par=-n means "leave n cores free" (number of cores - n - 1 script threads)
1240+
script_threads += GetNumCores();
1241+
}
1242+
1243+
// Subtract 1 because the main thread counts towards the par threads
1244+
script_threads = std::max(script_threads - 1, 0);
1245+
1246+
// Number of script-checking threads <= MAX_SCRIPTCHECK_THREADS
1247+
script_threads = std::min(script_threads, MAX_SCRIPTCHECK_THREADS);
1248+
1249+
LogPrintf("Script verification uses %d additional threads\n", script_threads);
1250+
if (script_threads >= 1) {
1251+
g_parallel_script_checks = true;
1252+
for (int i = 0; i < script_threads; ++i) {
12481253
threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
1254+
}
12491255
}
12501256

12511257
// Start the lightweight task scheduler thread

src/test/checkqueue_tests.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <util/memory.h>
66
#include <util/system.h>
77
#include <util/time.h>
8-
#include <validation.h>
98

109
#include <test/util/setup_common.h>
1110
#include <checkqueue.h>
@@ -19,11 +18,10 @@
1918

2019
#include <unordered_set>
2120

22-
// BasicTestingSetup not sufficient because nScriptCheckThreads is not set
23-
// otherwise.
2421
BOOST_FIXTURE_TEST_SUITE(checkqueue_tests, TestingSetup)
2522

2623
static const unsigned int QUEUE_BATCH_SIZE = 128;
24+
static const int SCRIPT_CHECK_THREADS = 3;
2725

2826
struct FakeCheck {
2927
bool operator()()
@@ -149,7 +147,7 @@ static void Correct_Queue_range(std::vector<size_t> range)
149147
{
150148
auto small_queue = MakeUnique<Correct_Queue>(QUEUE_BATCH_SIZE);
151149
boost::thread_group tg;
152-
for (auto x = 0; x < nScriptCheckThreads; ++x) {
150+
for (auto x = 0; x < SCRIPT_CHECK_THREADS; ++x) {
153151
tg.create_thread([&]{small_queue->Thread();});
154152
}
155153
// Make vChecks here to save on malloc (this test can be slow...)
@@ -214,7 +212,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure)
214212
auto fail_queue = MakeUnique<Failing_Queue>(QUEUE_BATCH_SIZE);
215213

216214
boost::thread_group tg;
217-
for (auto x = 0; x < nScriptCheckThreads; ++x) {
215+
for (auto x = 0; x < SCRIPT_CHECK_THREADS; ++x) {
218216
tg.create_thread([&]{fail_queue->Thread();});
219217
}
220218

@@ -246,7 +244,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Recovers_From_Failure)
246244
{
247245
auto fail_queue = MakeUnique<Failing_Queue>(QUEUE_BATCH_SIZE);
248246
boost::thread_group tg;
249-
for (auto x = 0; x < nScriptCheckThreads; ++x) {
247+
for (auto x = 0; x < SCRIPT_CHECK_THREADS; ++x) {
250248
tg.create_thread([&]{fail_queue->Thread();});
251249
}
252250

@@ -274,7 +272,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck)
274272
{
275273
auto queue = MakeUnique<Unique_Queue>(QUEUE_BATCH_SIZE);
276274
boost::thread_group tg;
277-
for (auto x = 0; x < nScriptCheckThreads; ++x) {
275+
for (auto x = 0; x < SCRIPT_CHECK_THREADS; ++x) {
278276
tg.create_thread([&]{queue->Thread();});
279277

280278
}
@@ -310,7 +308,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory)
310308
{
311309
auto queue = MakeUnique<Memory_Queue>(QUEUE_BATCH_SIZE);
312310
boost::thread_group tg;
313-
for (auto x = 0; x < nScriptCheckThreads; ++x) {
311+
for (auto x = 0; x < SCRIPT_CHECK_THREADS; ++x) {
314312
tg.create_thread([&]{queue->Thread();});
315313
}
316314
for (size_t i = 0; i < 1000; ++i) {
@@ -342,7 +340,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_FrozenCleanup)
342340
auto queue = MakeUnique<FrozenCleanup_Queue>(QUEUE_BATCH_SIZE);
343341
boost::thread_group tg;
344342
bool fails = false;
345-
for (auto x = 0; x < nScriptCheckThreads; ++x) {
343+
for (auto x = 0; x < SCRIPT_CHECK_THREADS; ++x) {
346344
tg.create_thread([&]{queue->Thread();});
347345
}
348346
std::thread t0([&]() {

src/test/util/setup_common.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,12 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
102102
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", FormatStateMessage(state)));
103103
}
104104

105-
nScriptCheckThreads = 3;
106-
for (int i = 0; i < nScriptCheckThreads - 1; i++)
105+
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
106+
constexpr int script_check_threads = 2;
107+
for (int i = 0; i < script_check_threads; ++i) {
107108
threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
109+
}
110+
g_parallel_script_checks = true;
108111

109112
m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
110113
m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.

src/validation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ CBlockIndex *pindexBestHeader = nullptr;
109109
Mutex g_best_block_mutex;
110110
std::condition_variable g_best_block_cv;
111111
uint256 g_best_block;
112-
int nScriptCheckThreads = 0;
112+
bool g_parallel_script_checks{false};
113113
std::atomic_bool fImporting(false);
114114
std::atomic_bool fReindex(false);
115115
bool fHavePruned = false;
@@ -2071,7 +2071,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
20712071

20722072
CBlockUndo blockundo;
20732073

2074-
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr);
2074+
CCheckQueueControl<CScriptCheck> control(fScriptChecks && g_parallel_script_checks ? &scriptcheckqueue : nullptr);
20752075

20762076
std::vector<int> prevheights;
20772077
CAmount nFees = 0;
@@ -2132,7 +2132,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
21322132
std::vector<CScriptCheck> vChecks;
21332133
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
21342134
TxValidationState tx_state;
2135-
if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : nullptr)) {
2135+
if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
21362136
// Any transaction validation failure in ConnectBlock is a block consensus failure
21372137
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
21382138
tx_state.GetRejectReason(), tx_state.GetDebugMessage());

src/validation.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
7777
/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
7878
static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
7979

80-
/** Maximum number of script-checking threads allowed */
81-
static const int MAX_SCRIPTCHECK_THREADS = 16;
80+
/** Maximum number of dedicated script-checking threads allowed */
81+
static const int MAX_SCRIPTCHECK_THREADS = 15;
8282
/** -par default (number of script-checking threads, 0 = auto) */
8383
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
8484
/** Number of blocks that can be requested at any given time from a single peer. */
@@ -147,7 +147,10 @@ extern std::condition_variable g_best_block_cv;
147147
extern uint256 g_best_block;
148148
extern std::atomic_bool fImporting;
149149
extern std::atomic_bool fReindex;
150-
extern int nScriptCheckThreads;
150+
/** Whether there are dedicated script-checking threads running.
151+
* False indicates all script checking is done on the main threadMessageHandler thread.
152+
*/
153+
extern bool g_parallel_script_checks;
151154
extern bool fRequireStandard;
152155
extern bool fCheckBlockIndex;
153156
extern bool fCheckpointsEnabled;

0 commit comments

Comments
 (0)