ParallelManager.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #ifndef ANKI_CORE_PARALLEL_MANAGER_H
  2. #define ANKI_CORE_PARALLEL_MANAGER_H
  3. #include "anki/util/Barrier.h"
  4. #include "anki/util/Singleton.h"
  5. #include <thread>
  6. #include <boost/ptr_container/ptr_vector.hpp>
  7. namespace anki {
  8. class ParallelManager;
  9. class ParallelJob;
  10. /// The base class of the parameters the we pass in the job
  11. struct ParallelJobParameters
  12. {};
  13. /// The callback that we feed to the job
  14. typedef void (*ParallelJobCallback)(ParallelJobParameters&, const ParallelJob&);
  15. /// The thread that executes a ParallelJobCallback
  16. class ParallelJob
  17. {
  18. public:
  19. /// Constructor
  20. ParallelJob(uint32_t id, const ParallelManager* manager,
  21. Barrier* barrier);
  22. /// @name Accessors
  23. /// @{
  24. uint32_t getId() const
  25. {
  26. return id;
  27. }
  28. const ParallelManager& getManager() const
  29. {
  30. return *manager;
  31. }
  32. /// @}
  33. /// Assign new job to the thread
  34. void assignNewJob(ParallelJobCallback callback,
  35. ParallelJobParameters& jobParams);
  36. private:
  37. uint32_t id; ///< An ID
  38. std::thread thread; ///< Runs the workingFunc
  39. std::mutex mutex; ///< Protect the ParallelJob::job
  40. std::condition_variable condVar; ///< To wake up the thread
  41. Barrier* barrier; ///< For synchronization
  42. ParallelJobCallback callback; ///< Its NULL if there are no pending job
  43. ParallelJobParameters* params;
  44. /// Know your father and pass him to the jobs
  45. const ParallelManager* manager;
  46. /// Start thread
  47. void start()
  48. {
  49. thread = std::thread(&ParallelJob::workingFunc, this);
  50. }
  51. /// Thread loop
  52. void workingFunc();
  53. };
  54. /// Parallel job dispatcher.You feed it with jobs and sends them for
  55. /// execution in parallel and then waits for all to finish
  56. class ParallelManager
  57. {
  58. public:
  59. /// Default constructor
  60. ParallelManager()
  61. {}
  62. /// Constructor #2
  63. ParallelManager(uint threadsNum)
  64. {
  65. init(threadsNum);
  66. }
  67. /// Init the manager
  68. void init(uint threadsNum);
  69. /// Assign a job to a working thread
  70. void assignNewJob(uint jobId, ParallelJobCallback callback,
  71. ParallelJobParameters& jobParams)
  72. {
  73. jobs[jobId].assignNewJob(callback, jobParams);
  74. }
  75. /// Wait for all jobs to finish
  76. void waitForAllJobsToFinish()
  77. {
  78. barrier->wait();
  79. }
  80. uint getThreadsNum() const
  81. {
  82. return jobs.size();
  83. }
  84. private:
  85. boost::ptr_vector<ParallelJob> jobs; ///< Worker threads
  86. std::unique_ptr<Barrier> barrier; ///< Synchronization barrier
  87. };
  88. /// Singleton
  89. typedef Singleton<ParallelManager> ParallelManagerSingleton;
  90. } // end namespace anki
  91. #endif