ThreadJobManager.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright (C) 2009-present, 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. #include <AnKi/Util/Function.h>
  8. #include <AnKi/Util/DynamicArray.h>
  9. namespace anki {
  10. /// @addtogroup util_thread
  11. /// @{
  12. /// Parallel task dispatcher. You feed it with tasks and sends them for execution in parallel and then waits for all to finish.
  13. class ThreadJobManager
  14. {
  15. public:
  16. using Func = Function<void(U32 threadId)>;
  17. /// Constructor.
  18. ThreadJobManager(U32 threadCount, Bool pinToCores = false, U32 queueSize = 256);
  19. ThreadJobManager(const ThreadJobManager&) = delete; // Non-copyable
  20. ~ThreadJobManager();
  21. ThreadJobManager& operator=(const ThreadJobManager&) = delete; // Non-copyable
  22. /// Assign a task to a working thread
  23. void dispatchTask(const Func& func)
  24. {
  25. m_tasksInFlightCount.fetchAdd(1);
  26. while(!pushBackTask(func))
  27. {
  28. m_cvar.notifyOne();
  29. std::this_thread::yield();
  30. }
  31. m_cvar.notifyOne();
  32. }
  33. /// Wait for all tasks to finish.
  34. void waitForAllTasksToFinish()
  35. {
  36. while(m_tasksInFlightCount.load() != 0)
  37. {
  38. m_cvar.notifyOne();
  39. std::this_thread::yield();
  40. }
  41. }
  42. U32 getThreadCount() const
  43. {
  44. return m_threads.getSize();
  45. }
  46. private:
  47. class WorkerThread;
  48. DynamicArray<WorkerThread*> m_threads;
  49. DynamicArray<Func> m_tasks;
  50. U32 m_tasksFront = 0;
  51. U32 m_tasksBack = 0;
  52. Mutex m_tasksMtx;
  53. Atomic<U32> m_tasksInFlightCount = {0};
  54. ConditionVariable m_cvar;
  55. Mutex m_mtx;
  56. Bool m_quit = false;
  57. Bool pushBackTask(const Func& func);
  58. Bool popFrontTask(Func& func);
  59. void threadRun(U32 threadId);
  60. };
  61. /// @}
  62. } // end namespace anki