GENEIAL  0.2=/
 All Classes Pages
ThreadedExecutionManager.hpp
1 #pragma once
2 
3 #include <geneial/utility/ThreadedExecutionManager.h>
4 
5 geneial_private_namespace(geneial)
6 {
7 geneial_private_namespace(utility)
8 {
9 
10 geneial_export_namespace
11 {
12 void ThreadedExecutionManager::executor()
13 {
14  std::deque<std::function<void()>> innerTask;
15 
16  bool running = true;
17  while (running)
18  {
19  std::unique_lock<std::mutex> l(_mutex);
20  _condEntry.wait(l, [this]()
21  {
22  return _finish || _tasks.size() != 0;
23  });
24 
25  if (!_tasks.empty())
26  {
27  int i = _amountPerThread;
28 
29  while (i-- && !_tasks.empty())
30  {
31  auto task = _tasks.front();
32  _tasks.pop_front();
33  innerTask.emplace_back(task);
34  }
35  const size_t taskToProcess = innerTask.size();
36  _activeTasks += taskToProcess;
37  l.unlock();
38 
39  size_t processedTasks = 0;
40  for (auto task : innerTask)
41  {
42  processedTasks++;
43  task();
44  }
45  innerTask.clear();
46  assert(processedTasks == taskToProcess);
47  l.lock();
48  _activeTasks -= processedTasks;
49  }
50  else
51  {
52  running = !_finish;
53  }
54 
55  _condExit.notify_all();
56  }
57 }
58 
59 void ThreadedExecutionManager::initializeThreads(const unsigned int amountThreads)
60 {
61  for (unsigned int i = 0; i < amountThreads; ++i)
62  {
63  _threads.emplace_back(
64  std::make_shared<std::thread>(&ThreadedExecutionManager::executor, this));
65  }
66 }
67 
68 void ThreadedExecutionManager::addTask(std::function<void()> const &task)
69 {
70  std::unique_lock < std::mutex > l(_mutex);
71  _tasks.emplace_back(task);
72  _condEntry.notify_one();
73 }
74 
75 void ThreadedExecutionManager::waitForTasks()
76 {
77  unsigned int activeTasks = 0;
78  do
79  {
80  std::unique_lock < std::mutex > l(_mutex);
81  activeTasks = _tasks.size() + _activeTasks;
82  if (activeTasks != 0)
83  {
84  _condExit.wait(l, [this]()
85  { return _tasks.size() == 0 && _activeTasks == 0;});
86  }
87  } while (activeTasks != 0);
88 }
89 
90 void ThreadedExecutionManager::joinAll()
91 {
92  {
93  std::unique_lock < std::mutex > l(_mutex);
94  _finish = true;
95  }
96  _condEntry.notify_all();
97  for (auto t : _threads)
98  {
99  t->join();
100  }
101 }
102 
103 } /* geneial_export_namespace */
104 } /* private namespace utility */
105 } /* private namespace geneial */