diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index d26a5a1963..c0329c0449 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -177,6 +177,7 @@ test.unit_test > xrpl.protocol tests.libxrpl > xrpl.basics tests.libxrpl > xrpl.json tests.libxrpl > xrpl.net +tests.libxrpl > xrpl.nodestore tests.libxrpl > xrpl.protocol tests.libxrpl > xrpl.protocol_autogen xrpl.conditions > xrpl.basics diff --git a/src/libxrpl/nodestore/backend/Backend.cpp b/src/libxrpl/nodestore/backend/Backend.cpp index 443ae15f61..58924a31b3 100644 --- a/src/libxrpl/nodestore/backend/Backend.cpp +++ b/src/libxrpl/nodestore/backend/Backend.cpp @@ -17,6 +17,22 @@ unsigned int const Backend::numHardwareThreads = []() { std::pair Backend::calculateBatchParallelism(unsigned int batchSize, unsigned int maxThreadCount) { + XRPL_ASSERT( + maxThreadCount > 0, + "xrpl::NodeStore::Backend::calculateBatchParallelism : maxThreadCount > 0"); + if (maxThreadCount == 0) + { + // LCOV_EXCL_START + UNREACHABLE("xrpl::NodeStore::Backend::calculateBatchParallelism : maxThreadCount == 0"); + return {1, batchSize}; + // LCOV_EXCL_STOP + } + + if (batchSize == 0) + { + return {0, 0}; + } + // Estimate the number of threads using ceiling division: aim for at least 4 items per thread, // but don't exceed the number of available threads. auto const initialThreads = std::min((batchSize + 3u) / 4u, maxThreadCount); @@ -28,7 +44,6 @@ Backend::calculateBatchParallelism(unsigned int batchSize, unsigned int maxThrea // threads than initially estimated. auto const actualThreads = (batchSize + numItems - 1u) / numItems; - // Sanity checks. XRPL_ASSERT( numItems <= batchSize, "xrpl::NodeStore::Backend::calculateBatchParallelism : numItems <= batchSize"); diff --git a/src/libxrpl/nodestore/backend/NuDBFactory.cpp b/src/libxrpl/nodestore/backend/NuDBFactory.cpp index 602f5de005..856b3370eb 100644 --- a/src/libxrpl/nodestore/backend/NuDBFactory.cpp +++ b/src/libxrpl/nodestore/backend/NuDBFactory.cpp @@ -80,7 +80,7 @@ public: shutdown_.store(true, std::memory_order_release); // Wait for all active operations to complete. - while (pendingReads_.load(std::memory_order_acquire) > 0 && + while (pendingReads_.load(std::memory_order_acquire) > 0 || pendingWrites_.load(std::memory_order_acquire) > 0) { std::this_thread::yield(); @@ -275,8 +275,9 @@ public: auto const [numThreads, numItems] = Backend::calculateBatchParallelism(hashes.size(), numHardwareThreads); - // If we need only one thread, just do it sequentially. - if (numThreads == 1u) + // If we need only one thread, just do it sequentially. Although it should be impossible to + // get 0 threads here, handle it gracefully just in case. + if (numThreads <= 1u) { for (size_t i = 0; i < hashes.size(); ++i) { @@ -424,8 +425,9 @@ public: auto const [numThreads, numItems] = Backend::calculateBatchParallelism(batch.size(), numHardwareThreads); - // If we need only one thread, just do it sequentially. - if (numThreads == 1u) + // If we need only one thread, just do it sequentially. Although it should be impossible to + // get 0 threads here, handle it gracefully just in case. + if (numThreads <= 1u) { for (auto const& e : batch) {