Helios++
Helios software for LiDAR simulations
WarehouseThreadPool.h
1 #pragma once
2 
3 #include <ThreadPool.h>
4 #include <TaskWarehouse.h>
5 
6 #include <memory>
7 
8 using std::shared_ptr;
9 
17 template <typename Task>
19 protected:
22  // *** ATTRIBUTES *** //
23  // ********************* //
37  bool working;
52  boost::mutex mtx;
57  boost::condition_variable condvar;
64  boost::mutex joinMtx;
71  boost::condition_variable joinCondvar;
72 
73 
74  // *** CONSTRUCTION / DESTRUCTION *** //
75  // ************************************ //
82  std::size_t const _pool_size,
83  std::size_t const maxTasks=256
84  ) :
85  ThreadPool(_pool_size),
86  warehouse(maxTasks),
87  working(true),
88  workersCount(0),
89  pendingCount(0)
90  {}
91  virtual ~WarehouseThreadPool() = default;
92 
93 public:
94  // *** WAREHOUSE THREADPOOL *** //
95  // ****************************** //
100  virtual inline bool post(shared_ptr<Task> task)
101  {return warehouse.post(task);}
106  virtual inline bool post(vector<shared_ptr<Task>> &tasks)
107  {return warehouse.post(tasks);}
112  virtual inline shared_ptr<Task> get()
113  {return warehouse.get();}
118  virtual inline void notify()
119  {warehouse.notify();}
124  virtual inline void notifyAll()
125  {warehouse.notifyAll();}
126 
134  virtual void start(){
135  // Start threads
137  for(size_t tid = 0 ; tid < pool_size ; ++tid){
138  io_service_.post(
139  boost::bind(
141  this,
142  tid
143  )
144  );
145  }
146  }
147 
151  virtual void join(){
152  boost::unique_lock<boost::mutex> lock(joinMtx);
153  while(pendingCount>0){
154  joinCondvar.wait(lock);
155  }
156  }
157 
163  virtual void finish(){
164  warehouse.notifyAllUpdate(working, false);
165  finalJoin();
166  }
167 
168 protected:
182  virtual void _start(size_t const tid){
183  shared_ptr<Task> task;
184 
185  // Standard working mode : Compute tasks and wait for new ones
186  while(working){
187  boost::unique_lock<boost::mutex> lockIncrease(joinMtx);
188  ++pendingCount;
189  lockIncrease.unlock();
190  while( (task=warehouse.get()) != nullptr){
191  doTask(tid, task);
192  }
193  boost::unique_lock<boost::mutex> lockDecrease(joinMtx);
194  --pendingCount;
195  lockDecrease.unlock();
196  joinCondvar.notify_one();
197  warehouse.waitIf(working);
198  }
199 
200  // Finishing mode : Consume pending tasks
201  if(warehouse.hasPendingTasks()){
202  boost::unique_lock<boost::mutex> lockIncrease(joinMtx);
203  ++pendingCount;
204  lockIncrease.unlock();
205  while( (task=warehouse.get()) != nullptr){
206  doTask(tid, task);
207  }
208  boost::unique_lock<boost::mutex> lockDecrease(joinMtx);
209  --pendingCount;
210  lockDecrease.unlock();
211  joinCondvar.notify_one();
212  }
213 
214  // Finish : Decrement from workers count
215  boost::unique_lock<boost::mutex> lock(mtx);
216  --workersCount;
217  lock.unlock();
218  condvar.notify_one();
219  }
220 
228  virtual void doTask(size_t const tid, shared_ptr<Task> task){
229  (*task)();
230  }
231 
237  virtual void finalJoin(){
238  boost::unique_lock<boost::mutex> lock(mtx);
239  while(workersCount > 0){
240  condvar.wait(lock);
241  }
242  }
243 
244 
245 };
Class implementing a warehouse to store and retrieve tasks in a thread safe fashion.
Definition: TaskWarehouse.h:22
Base class providing core implementation of a thread pool to deal with multi threading tasks.
Definition: ThreadPool.h:28
std::size_t pool_size
Size of thread pool (number of threads)
Definition: ThreadPool.h:47
boost::asio::io_service io_service_
Instance of boost input/output service for asynchronous data processing.
Definition: ThreadPool.h:36
Thread pool which starts thread so they are always waiting for new tasks to be posted to the warehous...
Definition: WarehouseThreadPool.h:18
virtual void finalJoin()
Lock until all pending tasks have been finished. If it is not called after finish,...
Definition: WarehouseThreadPool.h:237
std::size_t pool_size
Size of thread pool (number of threads)
Definition: ThreadPool.h:47
virtual void finish()
Finish the warehouse thread pool in a proper way. It is, allowing all tasks to finish properly and em...
Definition: WarehouseThreadPool.h:163
boost::mutex mtx
Mutex to handle concurrent access to workers count.
Definition: WarehouseThreadPool.h:52
boost::asio::io_service io_service_
Instance of boost input/output service for asynchronous data processing.
Definition: ThreadPool.h:36
boost::mutex joinMtx
Mutex to handle join until warehouse is empty (not the final join)
Definition: WarehouseThreadPool.h:64
virtual void notify()
Expose the warehouse notify method.
Definition: WarehouseThreadPool.h:118
virtual void join()
Lock until warehouse is empty.
Definition: WarehouseThreadPool.h:151
virtual void start()
Start the warehouse thread pool.
Definition: WarehouseThreadPool.h:134
WarehouseThreadPool(std::size_t const _pool_size, std::size_t const maxTasks=256)
Warehouse thread pool constructor.
Definition: WarehouseThreadPool.h:81
virtual bool post(vector< shared_ptr< Task >> &tasks)
Expose the warehouse post method.
Definition: WarehouseThreadPool.h:106
boost::condition_variable condvar
Conditional variable to handle concurrent access to workers count.
Definition: WarehouseThreadPool.h:57
TaskWarehouse< Task > warehouse
The task warehouse used to handle tasks.
Definition: WarehouseThreadPool.h:27
boost::condition_variable joinCondvar
Conditional variable to handle join until warehouse is empty (not the final join)
Definition: WarehouseThreadPool.h:71
bool working
True if thread pool is working, false if it is already finished.
Definition: WarehouseThreadPool.h:37
int pendingCount
Count how many workers with pending tasks there are. It is used for join (not final join)....
Definition: WarehouseThreadPool.h:48
virtual bool post(shared_ptr< Task > task)
Expose the warehouse post method.
Definition: WarehouseThreadPool.h:100
virtual void notifyAll()
Expose the warehouse notify all method.
Definition: WarehouseThreadPool.h:124
virtual void _start(size_t const tid)
Start a thread.
Definition: WarehouseThreadPool.h:182
int workersCount
Count how many active workers there are. It is used for final join.
Definition: WarehouseThreadPool.h:42
virtual shared_ptr< Task > get()
Expose the warehouse get method.
Definition: WarehouseThreadPool.h:112
virtual void doTask(size_t const tid, shared_ptr< Task > task)
Thread execute given task. By default it assumes task must be called with no arguments....
Definition: WarehouseThreadPool.h:228