Botan  2.11.0
Crypto and TLS for C++11
thread_pool.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2019 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/internal/thread_pool.h>
8 #include <botan/internal/os_utils.h>
9 #include <botan/exceptn.h>
10 #include <thread>
11 
12 namespace Botan {
13 
14 //static
16  {
17  static Thread_Pool g_thread_pool(OS::read_env_variable_sz("BOTAN_THREAD_POOL_SIZE"));
18  return g_thread_pool;
19  }
20 
21 Thread_Pool::Thread_Pool(size_t pool_size)
22  {
23  if(pool_size == 0)
24  {
25  pool_size = OS::get_cpu_available();
26 
27  /*
28  * For large machines don't create too many threads, unless
29  * explicitly asked to by the caller.
30  */
31  if(pool_size > 16)
32  pool_size = 16;
33  }
34 
35  if(pool_size <= 1)
36  pool_size = 2;
37 
38  m_shutdown = false;
39 
40  for(size_t i = 0; i != pool_size; ++i)
41  {
42  m_workers.push_back(std::thread(&Thread_Pool::worker_thread, this));
43  }
44  }
45 
47  {
48  {
49  std::unique_lock<std::mutex> lock(m_mutex);
50 
51  if(m_shutdown == true)
52  return;
53 
54  m_shutdown = true;
55 
56  m_more_tasks.notify_all();
57  }
58 
59  for(auto&& thread : m_workers)
60  {
61  thread.join();
62  }
63  m_workers.clear();
64  }
65 
66 void Thread_Pool::queue_thunk(std::function<void ()> fn)
67  {
68  std::unique_lock<std::mutex> lock(m_mutex);
69 
70  if(m_shutdown)
71  throw Invalid_State("Cannot add work after thread pool has shut down");
72 
73  m_tasks.push_back(fn);
74  m_more_tasks.notify_one();
75  }
76 
77 void Thread_Pool::worker_thread()
78  {
79  for(;;)
80  {
81  std::function<void()> task;
82 
83  {
84  std::unique_lock<std::mutex> lock(m_mutex);
85  m_more_tasks.wait(lock, [this]{ return m_shutdown || !m_tasks.empty(); });
86 
87  if(m_tasks.empty())
88  {
89  if(m_shutdown)
90  return;
91  else
92  continue;
93  }
94 
95  task = m_tasks.front();
96  m_tasks.pop_front();
97  }
98 
99  task();
100  }
101  }
102 
103 }
Thread_Pool(size_t pool_size=0)
Definition: thread_pool.cpp:21
void queue_thunk(std::function< void()>)
Definition: thread_pool.cpp:66
Definition: alg_id.cpp:13
size_t read_env_variable_sz(const std::string &var_name, size_t def_value=0)
Definition: os_utils.cpp:390
static Thread_Pool & global_instance()
Definition: thread_pool.cpp:15
size_t BOTAN_TEST_API get_cpu_available()
Definition: os_utils.cpp:223