You.i Engine
YiThreadPool.h
Go to the documentation of this file.
1 // © You i Labs Inc. 2000-2017. All rights reserved.
2 #ifndef _YI_THREAD_POOL_H_
3 #define _YI_THREAD_POOL_H_
4 
5 #include "thread/YiMutex.h"
6 #include "thread/YiStaticTask.h"
7 #include "thread/YiThread.h"
9 
10 #ifdef YI_DEBUG
11 #define YI_THREAD_POOL_INSTRUMENTED
12 #endif
13 
14 template <class ResultType>
15 class CYIFuture;
16 template <class ResultType>
17 class CYIStaticTask;
18 class CYITaskBase;
19 
40 {
41 public:
52  CYIThreadPool(const CYIString &sName = "ThreadPool", uint32_t uMaxSize = 4, uint32_t uMaxSleepingSize = 4, uint32_t uInitialSize = 2, uint32_t uExpiryTimeMs = 30000, YI_PRIORITY ePriority = YI_PRIORITY_DEFAULT, uint32_t uStackSize = CYIThread::DEFAULT_STACK_SIZE);
53  virtual ~CYIThreadPool();
54 
58  const CYIString &GetName() const;
59 
64  uint32_t GetSleepingThreadsCount() const;
65 
70  uint32_t GetThreadsCount() const;
71 
76  uint32_t GetPendingTasksCount() const;
77 
85  bool Queue(std::unique_ptr<CYITaskBase> pTask);
86 
90  void Shutdown();
91 
96  template<typename ResultType>
97  std::unique_ptr<CYIFuture<ResultType>> Queue(ResultType (*const pFunc)());
98 
105  template<typename ResultType, typename P1>
106  std::unique_ptr<CYIFuture<ResultType>> Queue(ResultType (*const pFunc)(P1), P1 const &funcParam1);
107 
114  template<typename ResultType, typename P1, typename P2>
115  std::unique_ptr<CYIFuture<ResultType>> Queue(ResultType (*const pFunc)(P1, P2), P1 const &funcParam1, P2 const &funcParam2);
116 
123  template<typename ResultType, typename P1, typename P2, typename P3>
124  std::unique_ptr<CYIFuture<ResultType>> Queue(ResultType (*const pFunc)(P1, P2, P3), P1 const &funcParam1, P2 const &funcParam2, P3 const &funcParam3);
125 
132  template<typename ResultType, typename P1, typename P2, typename P3, typename P4>
133  std::unique_ptr<CYIFuture<ResultType>> Queue(ResultType (*const pFunc)(P1, P2, P3, P4), P1 const &funcParam1, P2 const &funcParam2, P3 const &funcParam3, P4 const &funcParam4);
134 
139  template <typename ResultType>
140  bool QueueAndForget(ResultType (* const pFunc)());
141 
147  template <typename ResultType, typename P1>
148  bool QueueAndForget(ResultType (* const pFunc)(P1), P1 const &funcParam1);
149 
155  template <typename ResultType, typename P1, typename P2>
156  bool QueueAndForget(ResultType (* const pFunc)(P1, P2), P1 const &funcParam1, P2 const &funcParam2);
157 
163  template <typename ResultType, typename P1, typename P2, typename P3>
164  bool QueueAndForget(ResultType (* const pFunc)(P1, P2, P3), P1 const &funcParam1, P2 const &funcParam2, P3 const &funcParam3);
165 
171  template <typename ResultType, typename P1, typename P2, typename P3, typename P4>
172  bool QueueAndForget(ResultType (* const pFunc)(P1, P2, P3, P4), P1 const &funcParam1, P2 const &funcParam2, P3 const &funcParam3, P4 const &funcParam4);
173 
174 #ifdef YI_THREAD_POOL_INSTRUMENTED
175  struct Statistics
176  {
177  uint64_t m_uQueuedTasks;
178  uint64_t m_uExecutedTasks;
179  uint64_t m_uCancelledTasks;
180  float m_fCancelledTasksPercentage; // The percentage of queued tasks that have been cancelled (0..1).
181 
182  uint32_t m_uCreatedThreads;
183  uint32_t m_uDestroyedThreads;
184 
185  uint64_t m_uTasksThatMayHaveRunImmediately;
186  uint64_t m_uTasksThatLikelyHadToWaitForExecution;
187  float m_fBlockedTasksPercentage; // The percentage of queued tasks that may have had to wait until a worker thread was available (0..1).
188 
189  uint64_t m_uThreadTimeSpentExecutinguS;
190  uint64_t m_uThreadTimeSpentSleepinguS;
191  uint64_t m_uThreadTimeSpentOtheruS;
192  float m_fThreadWastePercentage;
193  float m_fThreadExecutionPercentage;
194  float m_fAverageTaskExecutionTimeuS;
195 
196  uint64_t m_uMinTaskWaitTimeuS;
197  uint64_t m_uMaxTaskWaitTimeuS;
198  float m_fAverageTaskWaitTimeuS;
199 
200  uint32_t m_uCurrentThreadsCount;
201  uint32_t m_uCurrentSleepingThreadsCount;
202  uint32_t m_uCurrentPendingTasksCount;
203  };
204 
214  Statistics GetStatistics();
215 
216 private:
217  std::atomic<uint64_t> m_nQueuedTasks{ 0 };
218  std::atomic<uint64_t> m_nExecutedTasks{ 0 };
219  std::atomic<uint64_t> m_nCancelledTasks{ 0 };
220 
221  std::atomic<uint32_t> m_nCreatedThreads{ 0 };
222  std::atomic<uint32_t> m_nDestroyedThreads{ 0 };
223 
224  std::atomic<uint64_t> m_nTasksThatMayHaveRunImmediately{ 0 };
225 
226  std::atomic<uint64_t> m_nThreadTimeSpentExecutinguS{ 0 };
227  std::atomic<uint64_t> m_nThreadTimeSpentSleepinguS{ 0 };
228  std::atomic<uint64_t> m_nThreadTimeSpentOtheruS{ 0 };
229 
230  std::atomic<uint64_t> m_nMinTaskWaitTimeuS{ 0 };
231  std::atomic<uint64_t> m_nMaxTaskWaitTimeuS{ 0 };
232  std::atomic<uint64_t> m_nTotalTaskWaitTimeuS{ 0 };
233 
234  mutable CYIMutex m_statisticsMutex;
235  std::map<const CYITaskBase *, uint64_t> m_taskQueueingTimes;
236 #endif
237 
238 private:
242  class WorkerThread : public CYIThread
243  {
244  public:
245  WorkerThread(CYIThreadPool *pParent, const CYIString &sName, YI_PRIORITY ePriority, uint32_t uStackSize);
246  virtual ~WorkerThread();
247  virtual void Run() override;
248  void CancelRunningTask();
249 
250  private:
251  CYIThreadPool *m_pParent;
252  std::unique_ptr<CYITaskBase> m_pCurrentTask;
253  CYIMutex m_taskMutex;
254  };
255 
256  WorkerThread *CreateWorker();
257  void AddWorker();
258  void AddWorkersIfNeeded();
259 
260  std::list<WorkerThread*> m_workers;
261  std::list<std::unique_ptr<CYITaskBase>> m_pendingTasks;
262  mutable CYIMutex m_mutex;
263  mutable CYIWaitCondition m_workAvailable;
264  mutable CYIWaitCondition m_workerCompleted;
265  bool m_bShutDown;
266  uint32_t m_uSleepingThreadsCount;
267  uint32_t m_uNextThreadNumber;
268  CYIThread *m_pWorkerPendingDeletion;
269 
270  CYIString m_sName;
271  uint32_t m_uMaxSize;
272  uint32_t m_uMaxSleepingSize;
273  uint64_t m_uExpiryTimeMs;
274  YI_PRIORITY m_ePriority;
275  uint32_t m_uStackSize;
276 };
277 
282 #include "YiThreadPool.inl"
283 
284 #endif // _YI_THREAD_POOL_H_
Definition: YiTask.h:24
uint32_t GetThreadsCount() const
Definition: YiMutex.h:110
Container class for Unicode strings. Conceptually, a CYIString object is a sequence of Unicode charac...
Definition: YiString.h:35
Definition: YiThreadPool.h:39
static const uint32_t DEFAULT_STACK_SIZE
Definition: YiThread.h:91
YI_PRIORITY
Definition: YiThread.h:14
bool Queue(std::unique_ptr< CYITaskBase > pTask)
CYIThreadPool(const CYIString &sName="ThreadPool", uint32_t uMaxSize=4, uint32_t uMaxSleepingSize=4, uint32_t uInitialSize=2, uint32_t uExpiryTimeMs=30000, YI_PRIORITY ePriority=YI_PRIORITY_DEFAULT, uint32_t uStackSize=CYIThread::DEFAULT_STACK_SIZE)
Definition: YiThread.h:24
Definition: YiStaticTask.h:37
const CYIString & GetName() const
bool QueueAndForget(ResultType(*const pFunc)())
uint32_t GetSleepingThreadsCount() const
Definition: YiFuture.h:139
Definition: YiThread.h:86
uint32_t GetPendingTasksCount() const
A class used to block a thread until a condition is met, as signaled by a different thread...
Definition: YiWaitCondition.h:64
virtual ~CYIThreadPool()