mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-07-25 15:49:13 +02:00
coins: introduce thread pool in CoinsViewOverlay
Introduce a ThreadPool shared pointer to CoinsViewOverlay. A pool managed externally can be passed in the constructor. A global thread pool is used in fuzz harnesses since iterations can happen faster than the OS can create and tear down thread pools. This can cause a memory leak when fuzzing. Co-authored-by: l0rinc <pap.lorinc@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <consensus/tx_check.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <kernel/chainstatemanager_opts.h>
|
||||
#include <kernel/cs_main.h>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
@@ -17,6 +18,7 @@
|
||||
#include <test/util/setup_common.h>
|
||||
#include <txdb.h>
|
||||
#include <util/hasher.h>
|
||||
#include <util/threadpool.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
@@ -84,6 +86,12 @@ public:
|
||||
|
||||
using CCoinsViewCache::CCoinsViewCache;
|
||||
};
|
||||
|
||||
// Reuse a single global thread pool across fuzz iterations. Creating and destroying a pool every
|
||||
// iteration leaks memory, since iterations can run faster than the OS can tear down the threads.
|
||||
std::shared_ptr<ThreadPool> g_thread_pool{std::make_shared<ThreadPool>("view_fuzz")};
|
||||
Mutex g_thread_pool_mutex;
|
||||
|
||||
} // namespace
|
||||
|
||||
void initialize_coins_view()
|
||||
@@ -376,10 +384,10 @@ FUZZ_TARGET(coins_view_db, .init = initialize_coins_view)
|
||||
// This allows us to exercise all methods on a CoinsViewOverlay, while also
|
||||
// ensuring that nothing can mutate the underlying cache until Flush or Sync is
|
||||
// called.
|
||||
FUZZ_TARGET(coins_view_overlay, .init = initialize_coins_view)
|
||||
FUZZ_TARGET(coins_view_overlay, .init = initialize_coins_view) EXCLUSIVE_LOCKS_REQUIRED(!g_thread_pool_mutex)
|
||||
{
|
||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||
MutationGuardCoinsViewCache backend_cache{&CoinsViewEmpty::Get(), /*deterministic=*/true};
|
||||
CoinsViewOverlay coins_view_cache{&backend_cache, /*deterministic=*/true};
|
||||
CoinsViewOverlay coins_view_cache{&backend_cache, g_thread_pool, /*deterministic=*/true};
|
||||
TestCoinsView(fuzzed_data_provider, coins_view_cache, &backend_cache);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
|
||||
#include <coins.h>
|
||||
#include <crypto/sha256.h>
|
||||
#include <kernel/chainstatemanager_opts.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/threadpool.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
@@ -182,10 +185,22 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Reuse a single global thread pool across fuzz iterations. Creating and destroying a pool every
|
||||
// iteration leaks memory, since iterations can run faster than the OS can tear down the threads.
|
||||
std::shared_ptr<ThreadPool> g_thread_pool{std::make_shared<ThreadPool>("cache_fuzz")};
|
||||
Mutex g_thread_pool_mutex;
|
||||
|
||||
void StartPoolIfNeeded() EXCLUSIVE_LOCKS_REQUIRED(!g_thread_pool_mutex)
|
||||
{
|
||||
LOCK(g_thread_pool_mutex);
|
||||
if (!g_thread_pool->WorkersCount()) g_thread_pool->Start(DEFAULT_PREVOUTFETCH_THREADS);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FUZZ_TARGET(coinscache_sim)
|
||||
FUZZ_TARGET(coinscache_sim, .init = [] { static auto setup{MakeNoLogFileContext<>()}; }) EXCLUSIVE_LOCKS_REQUIRED(!g_thread_pool_mutex)
|
||||
{
|
||||
StartPoolIfNeeded();
|
||||
/** Precomputed COutPoint and CCoins values. */
|
||||
static const PrecomputedData data;
|
||||
|
||||
@@ -372,7 +387,7 @@ FUZZ_TARGET(coinscache_sim)
|
||||
if (provider.ConsumeBool()) {
|
||||
caches.emplace_back(new CCoinsViewCache(&*caches.back(), /*deterministic=*/true));
|
||||
} else {
|
||||
caches.emplace_back(new CoinsViewOverlay(&*caches.back(), /*deterministic=*/true));
|
||||
caches.emplace_back(new CoinsViewOverlay(&*caches.back(), g_thread_pool, /*deterministic=*/true));
|
||||
}
|
||||
// Apply to simulation data.
|
||||
sim_caches[caches.size()].Wipe();
|
||||
|
||||
Reference in New Issue
Block a user