diff options
author | Jack Lloyd <[email protected]> | 2021-04-24 09:21:39 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2021-04-24 09:21:39 -0400 |
commit | bfc0e9c2d0d38190eed442d925313bb3268e830b (patch) | |
tree | 55ba08fe44f07b06bda0af9243ca04ca70741046 /src/lib/utils | |
parent | 225727ec8d5c057f8b9d419ca90904df0bb9feee (diff) | |
parent | da841c1055e00ebbb712e58c73596e9af675a53b (diff) |
Merge GH #2723 Allow disabling thread pool at runtime via env var
Diffstat (limited to 'src/lib/utils')
-rw-r--r-- | src/lib/utils/thread_utils/thread_pool.cpp | 50 | ||||
-rw-r--r-- | src/lib/utils/thread_utils/thread_pool.h | 16 |
2 files changed, 56 insertions, 10 deletions
diff --git a/src/lib/utils/thread_utils/thread_pool.cpp b/src/lib/utils/thread_utils/thread_pool.cpp index 405f79585..ce326fdc0 100644 --- a/src/lib/utils/thread_utils/thread_pool.cpp +++ b/src/lib/utils/thread_utils/thread_pool.cpp @@ -1,5 +1,5 @@ /* -* (C) 2019 Jack Lloyd +* (C) 2019,2021 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -11,19 +11,53 @@ namespace Botan { +namespace { + +std::optional<size_t> global_thread_pool_size() + { + std::string var; + if(OS::read_env_variable(var, "BOTAN_THREAD_POOL_SIZE")) + { + try + { + return std::optional<size_t>(std::stoul(var, nullptr)); + } + catch(std::exception&) { /* ignore it */ } + + if(var == "none") + return std::nullopt; + } + + // If it was neither a number nor a special value, then ignore it. + return std::optional<size_t>(0); + } + +} + //static Thread_Pool& Thread_Pool::global_instance() { - static Thread_Pool g_thread_pool(OS::read_env_variable_sz("BOTAN_THREAD_POOL_SIZE")); + static Thread_Pool g_thread_pool(global_thread_pool_size()); return g_thread_pool; } -Thread_Pool::Thread_Pool(size_t pool_size) +Thread_Pool::Thread_Pool(std::optional<size_t> opt_pool_size) { + m_shutdown = false; + + if(!opt_pool_size.has_value()) + return; + + size_t pool_size = opt_pool_size.value(); + if(pool_size == 0) { pool_size = OS::get_cpu_available(); + // Unclear if this can happen, but be defensive + if(pool_size == 0) + pool_size = 2; + /* * For large machines don't create too many threads, unless * explicitly asked to by the caller. @@ -32,11 +66,6 @@ Thread_Pool::Thread_Pool(size_t pool_size) pool_size = 16; } - if(pool_size <= 1) - pool_size = 2; - - m_shutdown = false; - for(size_t i = 0; i != pool_size; ++i) { m_workers.push_back(std::thread(&Thread_Pool::worker_thread, this)); @@ -70,6 +99,11 @@ void Thread_Pool::queue_thunk(std::function<void ()> fn) if(m_shutdown) throw Invalid_State("Cannot add work after thread pool has shut down"); + if(m_workers.empty()) + { + return fn(); + } + m_tasks.push_back(fn); m_more_tasks.notify_one(); } diff --git a/src/lib/utils/thread_utils/thread_pool.h b/src/lib/utils/thread_utils/thread_pool.h index 8f818d1b7..d94a0e75f 100644 --- a/src/lib/utils/thread_utils/thread_pool.h +++ b/src/lib/utils/thread_utils/thread_pool.h @@ -18,6 +18,7 @@ #include <thread> #include <future> #include <condition_variable> +#include <optional> namespace Botan { @@ -32,9 +33,20 @@ class BOTAN_TEST_API Thread_Pool /** * Initialize a thread pool with some number of threads * @param pool_size number of threads in the pool, if 0 - * then some default value is chosen + * then some default value is chosen. If the optional + * is nullopt then the thread pool is disabled; all + * work is executed immediately when queued. */ - Thread_Pool(size_t pool_size = 0); + Thread_Pool(std::optional<size_t> pool_size); + + /** + * Initialize a thread pool with some number of threads + * @param pool_size number of threads in the pool, if 0 + * then some default value is chosen. + */ + Thread_Pool(size_t pool_size = 0) : + Thread_Pool(std::optional<size_t>(pool_size)) + {} ~Thread_Pool() { shutdown(); } |