ThreadPool.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/util/Thread.h>
  7. namespace anki
  8. {
  9. // Forward
  10. namespace detail
  11. {
  12. class ThreadPoolThread;
  13. }
  14. /// @addtogroup util_thread
  15. /// @{
  16. /// A task assignment for a ThreadPool
  17. /// @memberof ThreadPool
  18. class ThreadPoolTask
  19. {
  20. public:
  21. virtual ~ThreadPoolTask()
  22. {
  23. }
  24. virtual Error operator()(U32 taskId, PtrSize threadsCount) = 0;
  25. /// Chose a starting and end index
  26. static void choseStartEnd(U32 taskId,
  27. PtrSize threadsCount,
  28. PtrSize elementsCount,
  29. PtrSize& start,
  30. PtrSize& end)
  31. {
  32. F32 tid = taskId;
  33. F32 div = F32(elementsCount) / threadsCount;
  34. start = PtrSize(tid * div);
  35. end = PtrSize((tid + 1.0) * div);
  36. }
  37. };
  38. /// Parallel task dispatcher. You feed it with tasks and sends them for
  39. /// execution in parallel and then waits for all to finish
  40. class ThreadPool : public NonCopyable
  41. {
  42. friend class detail::ThreadPoolThread;
  43. public:
  44. static constexpr U MAX_THREADS = 32; ///< An absolute limit
  45. /// Constructor
  46. ThreadPool(U32 threadsCount);
  47. ~ThreadPool();
  48. /// Assign a task to a working thread
  49. /// @param slot The slot of the task
  50. /// @param task The task. If it's nullptr then a dummy task will be assigned
  51. void assignNewTask(U32 slot, ThreadPoolTask* task);
  52. /// Wait for all tasks to finish.
  53. /// @return The error code in one of the worker threads.
  54. ANKI_USE_RESULT Error waitForAllThreadsToFinish()
  55. {
  56. m_barrier.wait();
  57. m_tasksAssigned = 0;
  58. Error err = m_err;
  59. m_err = ErrorCode::NONE;
  60. return err;
  61. }
  62. PtrSize getThreadsCount() const
  63. {
  64. return m_threadsCount;
  65. }
  66. private:
  67. /// A dummy task for a ThreadPool
  68. class DummyTask : public ThreadPoolTask
  69. {
  70. public:
  71. Error operator()(U32 taskId, PtrSize threadsCount)
  72. {
  73. (void)taskId;
  74. (void)threadsCount;
  75. return ErrorCode::NONE;
  76. }
  77. };
  78. Barrier m_barrier; ///< Synchronization barrier
  79. detail::ThreadPoolThread* m_threads = nullptr; ///< Threads array
  80. U m_tasksAssigned = 0;
  81. U8 m_threadsCount = 0;
  82. Error m_err = ErrorCode::NONE;
  83. static DummyTask m_dummyTask;
  84. };
  85. /// @}
  86. } // end namespace anki