diff --git a/include/dwarfs/reader/block_cache_options.h b/include/dwarfs/reader/block_cache_options.h index 6d4a7129..10efc53b 100644 --- a/include/dwarfs/reader/block_cache_options.h +++ b/include/dwarfs/reader/block_cache_options.h @@ -43,7 +43,6 @@ struct block_cache_options { size_t num_workers{0}; double decompress_ratio{1.0}; bool mm_release{true}; - bool init_workers{true}; bool disable_block_integrity_check{false}; size_t sequential_access_detector_threshold{0}; block_cache_allocation_mode allocation_mode{ diff --git a/src/reader/block_cache_options.cpp b/src/reader/block_cache_options.cpp index 8c26eef2..221e0556 100644 --- a/src/reader/block_cache_options.cpp +++ b/src/reader/block_cache_options.cpp @@ -37,9 +37,9 @@ namespace dwarfs::reader { std::ostream& operator<<(std::ostream& os, block_cache_options const& opts) { os << fmt::format( "max_bytes={}, num_workers={}, decompress_ratio={}, mm_release={}, " - "init_workers={}, disable_block_integrity_check={}", + "disable_block_integrity_check={}", opts.max_bytes, opts.num_workers, opts.decompress_ratio, opts.mm_release, - opts.init_workers, opts.disable_block_integrity_check); + opts.disable_block_integrity_check); return os; } diff --git a/src/reader/internal/block_cache.cpp b/src/reader/internal/block_cache.cpp index 1d0f6f11..bd1ed166 100644 --- a/src/reader/internal/block_cache.cpp +++ b/src/reader/internal/block_cache.cpp @@ -244,13 +244,6 @@ class block_cache_ final : public block_cache::impl { options.sequential_access_detector_threshold)} , os_{os} , options_(options) { - if (options.init_workers) { - wg_ = worker_group(lgr, os_, "blkcache", - std::max(options.num_workers > 0 - ? options.num_workers - : hardware_concurrency(), - static_cast(1))); - } cache_.set_prune_hook( [this](size_t block_no, std::shared_ptr&& block) { on_block_removed("evicted", block_no, std::move(block)); @@ -263,8 +256,12 @@ class block_cache_ final : public block_cache::impl { tidy_runner_.stop(); - if (wg_) { - wg_.stop(); + { + std::unique_lock lock(mx_wg_); + + if (wg_) { + wg_.stop(); + } } if (!blocks_created_.load()) { @@ -604,7 +601,22 @@ class block_cache_ final : public block_cache::impl { std::memory_order_relaxed); } + void init_worker_group() const { + std::unique_lock lock(mx_wg_); + + if (!wg_) { + wg_ = worker_group(LOG_GET_LOGGER, os_, "blkcache", + std::max(options_.num_workers > 0 + ? options_.num_workers + : hardware_concurrency(), + static_cast(1))); + } + } + void enqueue_job(std::shared_ptr brs) const { + // lazy initialization of worker group + std::call_once(wg_init_flag_, [this] { init_worker_group(); }); + std::shared_lock lock(mx_wg_); // Lambda needs to be mutable so we can actually move out of it @@ -789,6 +801,7 @@ class block_cache_ final : public block_cache::impl { mutable std::shared_mutex mx_wg_; mutable worker_group wg_; + mutable std::once_flag wg_init_flag_; std::vector block_; std::shared_ptr mm_; byte_buffer_factory buffer_factory_; diff --git a/tools/src/dwarfs_main.cpp b/tools/src/dwarfs_main.cpp index c2c10580..b61df0c7 100644 --- a/tools/src/dwarfs_main.cpp +++ b/tools/src/dwarfs_main.cpp @@ -1492,7 +1492,6 @@ void load_filesystem(dwarfs_userdata& userdata) { fsopts.block_cache.num_workers = opts.workers; fsopts.block_cache.decompress_ratio = opts.decompress_ratio; fsopts.block_cache.mm_release = !opts.cache_image; - fsopts.block_cache.init_workers = false; fsopts.block_cache.sequential_access_detector_threshold = opts.seq_detector_threshold; fsopts.block_cache.allocation_mode = opts.block_allocator;