No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

89 líneas
2.0 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include "./worker.h"
  4. #include "./types.h"
  5. beg_namespace_ecs_core_utils
  6. {
  7. struct thread_pool
  8. {
  9. private:
  10. using worker_vector = std::vector<thread_pool_worker>;
  11. using atomic_size_t = std::atomic<size_t>;
  12. private:
  13. task_queue _queue;
  14. worker_vector _workers;
  15. atomic_size_t _outstanding_inits;
  16. auto all_workers_finished() const noexcept
  17. {
  18. for (const auto& w : _workers)
  19. {
  20. if (!w.finished())
  21. {
  22. return false;
  23. }
  24. }
  25. return true;
  26. }
  27. inline void post_dummy_task()
  28. { post([]{ }); }
  29. void initialize_workers(size_t count)
  30. {
  31. _workers.reserve(count);
  32. for (size_t i = 0; i < count; ++i)
  33. {
  34. _workers.emplace_back(_queue);
  35. }
  36. _outstanding_inits = count;
  37. for (auto& w : _workers)
  38. {
  39. w.start(_outstanding_inits);
  40. }
  41. }
  42. public:
  43. inline thread_pool(size_t count)
  44. { initialize_workers(count); }
  45. ~thread_pool()
  46. {
  47. // wait for uninitialized workers
  48. while (_outstanding_inits > 0)
  49. {
  50. std::this_thread::sleep_for(std::chrono::milliseconds(50));
  51. }
  52. // stop all workers
  53. for (auto& w : _workers)
  54. {
  55. w.stop();
  56. }
  57. // post dummy tasks untill all workers has stopped
  58. while (!all_workers_finished())
  59. {
  60. post_dummy_task();
  61. }
  62. // join the worker threads
  63. for (auto& w : _workers)
  64. {
  65. w.join();
  66. }
  67. }
  68. template<typename T_func>
  69. inline void post(T_func&& func)
  70. { _queue.enqueue(std::forward<T_func>(func)); }
  71. };
  72. }
  73. end_namespace_ecs_core_utils