jubilant-funicular
ThreadPool.h
1 #ifndef NTA_THREADPOOL_H_INCLUDED
2 #define NTA_THREADPOOL_H_INCLUDED
3 
4 #include <thread>
5 #include <atomic>
6 #include <queue>
7 #include <mutex>
8 #include <functional>
9 #include <condition_variable>
10 
11 typedef std::function<void(void)> Thunk;
12 
14 namespace nta {
16  namespace utils {
17  class Semaphore {
18  private:
20  std::mutex m_mutex;
21  std::condition_variable_any m_cv;
23  int m_value;
24  public:
26  Semaphore(int value = 0);
28  void wait();
30  void signal();
31 
32  Semaphore(const Semaphore&) = delete;
33  const Semaphore& operator=(const Semaphore&) = delete;
34  };
36  class ThreadPool {
37  private:
39  struct worker {
41  std::thread t;
43  Thunk thunk;
45  std::atomic<bool> free;
46  // Notifies worker when it has a new task
47  Semaphore task;
48 
49  worker() : free(true) {}
50  };
51 
53  void dispatcher();
55  void worker_func(size_t wid);
57  size_t getAvailableWorker();
59  bool allWorkFinished();
60 
62  struct {
63  std::condition_variable_any cv;
64  std::mutex m;
65  } m_empty;
67  std::vector<worker> m_workers;
69  std::atomic<bool> m_kill;
75  std::queue<Thunk> m_funcs;
77  std::thread m_dispatch_thread;
78  public:
80  ThreadPool(size_t num_threads);
81  ~ThreadPool();
83  void schedule(const Thunk& thunk);
85  void wait();
86 
87  ThreadPool(const ThreadPool&) = delete;
88  ThreadPool& operator=(const ThreadPool&) = delete;
89  };
90  }
91 }
92 
93 #endif // NTA_THREADPOOL_H_INCLUDED
nta::utils::Semaphore::Semaphore
Semaphore(int value=0)
Constructs Semaphore with given value.
Definition: Semaphore.cpp:5
nta::utils::ThreadPool::worker::thunk
Thunk thunk
The function the worker is currently scheduled to execute.
Definition: ThreadPool.h:43
nta::utils::ThreadPool::m_funcs
std::queue< Thunk > m_funcs
The functions to be executed.
Definition: ThreadPool.h:75
nta::utils::ThreadPool::m_kill
std::atomic< bool > m_kill
Sign to kill the pool.
Definition: ThreadPool.h:69
nta::utils::ThreadPool::m_scheduled
Semaphore m_scheduled
Record of scheduled workers.
Definition: ThreadPool.h:71
nta::utils::Semaphore::wait
void wait()
Halts until value of Semaphore is > 0.
Definition: Semaphore.cpp:7
nta::utils::ThreadPool::wait
void wait()
Waits for all scheduled functions to finish execution.
Definition: ThreadPool.cpp:68
nta::utils::ThreadPool::m_available
Semaphore m_available
Record of available workers.
Definition: ThreadPool.h:73
nta::utils::ThreadPool::m_empty
struct nta::utils::ThreadPool::@6 m_empty
Used to keep track of when the pool is empty.
nta::utils::Semaphore::m_value
int m_value
The number of resources available.
Definition: ThreadPool.h:23
nta::utils::ThreadPool::worker
One thread available to the pool.
Definition: ThreadPool.h:39
nta::utils::ThreadPool::ThreadPool
ThreadPool(size_t num_threads)
Constructs a ThreadPool with specified number of threads.
Definition: ThreadPool.cpp:5
nta
Definition: Animation2D.h:6
nta::utils::Semaphore::signal
void signal()
Increments value of Semaphore.
Definition: Semaphore.cpp:12
nta::utils::ThreadPool::allWorkFinished
bool allWorkFinished()
Returns whether or not all work is finished.
Definition: ThreadPool.cpp:12
nta::utils::Semaphore
Definition: ThreadPool.h:17
nta::utils::ThreadPool::getAvailableWorker
size_t getAvailableWorker()
Returns id of an available worker.
Definition: ThreadPool.cpp:18
nta::utils::ThreadPool::dispatcher
void dispatcher()
Function run by dispatch thread.
Definition: ThreadPool.cpp:28
nta::utils::Semaphore::m_mutex
std::mutex m_mutex
Thread safety stuff.
Definition: ThreadPool.h:20
nta::utils::ThreadPool::schedule
void schedule(const Thunk &thunk)
Schedules a function to be executed.
Definition: ThreadPool.cpp:62
nta::utils::ThreadPool
Collection of threads for running scheduled functions.
Definition: ThreadPool.h:36
nta::utils::ThreadPool::worker_func
void worker_func(size_t wid)
Function run by worker threads.
Definition: ThreadPool.cpp:47
nta::utils::ThreadPool::worker::t
std::thread t
The thread owned by the worker.
Definition: ThreadPool.h:41
nta::utils::ThreadPool::m_dispatch_thread
std::thread m_dispatch_thread
The thread for managing the pool.
Definition: ThreadPool.h:77
nta::utils::ThreadPool::worker::free
std::atomic< bool > free
Whether or not the worker is free to take on a new function.
Definition: ThreadPool.h:45
nta::utils::ThreadPool::m_workers
std::vector< worker > m_workers
The workers.
Definition: ThreadPool.h:67