You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 line
3.6 KiB

  1. #pragma once
  2. #include <mutex>
  3. #include <thread>
  4. #include <condition_variable>
  5. #include <ecs/config.h>
  6. #include "./task_queue.h"
  7. #include "../movable_atomic.h"
  8. namespace ecs {
  9. namespace core {
  10. namespace utils {
  11. /**
  12. * worker thread to execute tasks of thread pool in
  13. */
  14. struct thread_pool_worker
  15. {
  16. private:
  17. /**
  18. * state of the worker
  19. */
  20. enum class state
  21. {
  22. uninizialized, //!< the thread was not initialized yes
  23. running, //!< the thread is running normally
  24. stopped, //!< the thread was intended to stop execution
  25. finished, //!< the thread has stopped execution
  26. };
  27. using atomic_state = movable_atomic<state>;
  28. std::thread _thread; //!< actual thread object to use for execution
  29. std::mutex _mutex; //!< mutex to protext the conditional
  30. std::condition_variable _conditional; //!< condition variable to inform about new tasks
  31. concurrent_task_queue& _all_tasks; //!< queue to poll new tasks from
  32. task_queue _own_tasks; //!< queue of tasks that are assigned to this specific worker
  33. atomic_state _state; //!< current state of the worker
  34. size_t _thread_id; //!< index of the thread inside the thread pool
  35. private:
  36. /**
  37. * thread worker method
  38. */
  39. void run();
  40. /**
  41. * pop the next task from either the own task list or the general task list
  42. *
  43. * @param t parameter to store dequeued task in
  44. * @param timeout timeout to wait for new tasks
  45. *
  46. * @return TRUE if a task was dequeued, FALSE otherwise
  47. */
  48. template<typename T_rep, typename T_period>
  49. inline bool pop(task& t, const std::chrono::duration<T_rep, T_period>& timeout);
  50. public:
  51. /**
  52. * constructor
  53. *
  54. * @param queue task queue to poll tasks from
  55. */
  56. inline thread_pool_worker(concurrent_task_queue& all_tasks, size_t thread_id) noexcept;
  57. inline thread_pool_worker(thread_pool_worker&&) = default;
  58. inline thread_pool_worker(const thread_pool_worker&) = delete;
  59. inline thread_pool_worker& operator=(thread_pool_worker&&) = default;
  60. inline thread_pool_worker& operator=(const thread_pool_worker&) = delete;
  61. /**
  62. * start the worker
  63. *
  64. * @tparam T_counter type of the counter
  65. *
  66. * @param remaining_inits number of remaining thread initialization (is decremented by this thread)
  67. */
  68. template<typename T_counter>
  69. inline void start(T_counter& remaining_inits);
  70. /**
  71. * stop the thread execution
  72. */
  73. inline void stop() noexcept;
  74. /**
  75. * wait for the thread to finish
  76. */
  77. inline void join() noexcept;
  78. /**
  79. * check if the thread has stopped execution
  80. *
  81. * @retval TRUE if the thread has stopped execution
  82. * @retval FALSE if the thread is still running
  83. */
  84. inline bool finished() const noexcept;
  85. /**
  86. * enqueue a new task to execute inside this worker thread
  87. *
  88. * @tparam T_task type of the task
  89. *
  90. * @param task task to execute
  91. */
  92. template<typename T_task>
  93. inline void post(T_task&& task);
  94. /**
  95. * inform the task about new tasks in the concurent task list
  96. */
  97. inline void signal();
  98. };
  99. } } }