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.

66 líneas
2.0 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include <ecs/core/system/data_proxy.h>
  4. namespace ecs {
  5. namespace core {
  6. namespace system {
  7. namespace parallelism {
  8. struct split_base
  9. {
  10. public:
  11. template<typename T_context, typename T_instance>
  12. struct executor_proxy
  13. {
  14. public:
  15. using context_type = T_context;
  16. using instance_type = T_instance;
  17. context_type& context;
  18. instance_type& instance;
  19. size_t split_count;
  20. size_t per_split;
  21. public:
  22. template<typename T_func>
  23. inline void for_subtasks(T_func&& func)
  24. {
  25. auto total_count = instance.subscribed_count();
  26. instance.prepare_states(split_count);
  27. utils::counter_blocker counter(split_count - 1);
  28. /* execute the splitted subtask */
  29. auto execute = [this, &func](size_t index, size_t from, size_t to)
  30. {
  31. auto data = data_proxy::make_multi(context, instance, index, from, to);
  32. func(data);
  33. };
  34. /* create subtasks */
  35. for (size_t i = 0; i < split_count - 1; ++i)
  36. {
  37. context.post_in_thread_pool([this, &counter, &execute, i](auto){
  38. ecs_make_scope_guard([&counter](){
  39. counter.decrement();
  40. });
  41. auto beg = i * per_split;
  42. auto end = (i + 1) * per_split;
  43. execute(i, beg, end);
  44. });
  45. }
  46. /* execute and wait */
  47. counter.execute_and_wait([this, &execute, total_count]{
  48. auto index = split_count - 1;
  49. auto beg = index * per_split;
  50. auto end = total_count;
  51. execute(index, beg, end);
  52. });
  53. }
  54. };
  55. };
  56. } } } }