• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 6362617071

30 Sep 2023 11:54AM UTC coverage: 91.751% (-0.01%) from 91.763%
6362617071

push

github

web-flow
Merge pull request #3628 from randombit/thread_pool_debug

thead pool debugging support proposal using native capabilities if po…

79497 of 86644 relevant lines covered (91.75%)

8513342.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.38
/src/lib/utils/thread_utils/thread_pool.cpp
1
/*
2
* (C) 2019,2021 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

9
#include <botan/exceptn.h>
10
#include <botan/internal/os_utils.h>
11
#include <thread>
12

13
namespace Botan {
14

15
namespace {
16

17
std::optional<size_t> global_thread_pool_size() {
752✔
18
   std::string var;
752✔
19
   if(OS::read_env_variable(var, "BOTAN_THREAD_POOL_SIZE")) {
752✔
20
      try {
×
21
         return std::optional<size_t>(std::stoul(var, nullptr));
×
22
      } catch(std::exception&) { /* ignore it */
×
23
      }
×
24

25
      if(var == "none") {
×
26
         return std::nullopt;
×
27
      }
28
   }
29

30
   // If it was neither a number nor a special value, then ignore it.
31
   return std::optional<size_t>(0);
752✔
32
}
752✔
33

34
}  // namespace
35

36
//static
37
Thread_Pool& Thread_Pool::global_instance() {
6,340✔
38
   static Thread_Pool g_thread_pool(global_thread_pool_size());
6,340✔
39
   return g_thread_pool;
6,340✔
40
}
41

42
Thread_Pool::Thread_Pool(std::optional<size_t> opt_pool_size) {
754✔
43
   m_shutdown = false;
754✔
44
   // On Linux, it is 16 length max, including terminator
45
   const std::string tname = "Botan thread";
754✔
46

47
   if(!opt_pool_size.has_value()) {
754✔
48
      return;
×
49
   }
50

51
   size_t pool_size = opt_pool_size.value();
754✔
52

53
   if(pool_size == 0) {
754✔
54
      pool_size = OS::get_cpu_available();
753✔
55

56
      // Unclear if this can happen, but be defensive
57
      if(pool_size == 0) {
753✔
58
         pool_size = 2;
59
      }
60

61
      /*
62
      * For large machines don't create too many threads, unless
63
      * explicitly asked to by the caller.
64
      */
65
      if(pool_size > 16) {
753✔
66
         pool_size = 16;
67
      }
68
   }
69

70
   m_workers.resize(pool_size);
754✔
71

72
   for(size_t i = 0; i != pool_size; ++i) {
2,276✔
73
      m_workers[i] = std::thread(&Thread_Pool::worker_thread, this);
1,522✔
74
      OS::set_thread_name(m_workers[i], tname);
1,522✔
75
   }
76
}
754✔
77

78
void Thread_Pool::shutdown() {
756✔
79
   {
756✔
80
      std::unique_lock<std::mutex> lock(m_mutex);
756✔
81

82
      if(m_shutdown == true) {
756✔
83
         return;
2✔
84
      }
85

86
      m_shutdown = true;
754✔
87

88
      m_more_tasks.notify_all();
754✔
89
   }
2✔
90

91
   for(auto&& thread : m_workers) {
2,276✔
92
      thread.join();
1,522✔
93
   }
94
   m_workers.clear();
754✔
95
}
96

97
void Thread_Pool::queue_thunk(const std::function<void()>& fn) {
205,040✔
98
   std::unique_lock<std::mutex> lock(m_mutex);
205,040✔
99

100
   if(m_shutdown) {
205,040✔
101
      throw Invalid_State("Cannot add work after thread pool has shut down");
×
102
   }
103

104
   if(m_workers.empty()) {
205,040✔
105
      return fn();
×
106
   }
107

108
   m_tasks.push_back(fn);
205,040✔
109
   m_more_tasks.notify_one();
205,040✔
110
}
205,040✔
111

112
void Thread_Pool::worker_thread() {
1,522✔
113
   for(;;) {
206,562✔
114
      std::function<void()> task;
206,562✔
115

116
      {
206,562✔
117
         std::unique_lock<std::mutex> lock(m_mutex);
206,562✔
118
         m_more_tasks.wait(lock, [this] { return m_shutdown || !m_tasks.empty(); });
227,115✔
119

120
         if(m_tasks.empty()) {
206,562✔
121
            if(m_shutdown) {
1,522✔
122
               return;
1,522✔
123
            } else {
124
               continue;
×
125
            }
126
         }
127

128
         task = m_tasks.front();
205,040✔
129
         m_tasks.pop_front();
205,040✔
130
      }
1,522✔
131

132
      task();
410,080✔
133
   }
206,562✔
134
}
135

136
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc