|
- #pragma once
-
- #include <ecs/config.h>
- #include <ecs/core/system/data_proxy.h>
-
- namespace ecs {
- namespace core {
- namespace system {
- namespace parallelism {
-
- struct split_base
- {
- public:
- template<typename T_context, typename T_instance>
- struct executor_proxy
- {
- public:
- using context_type = T_context;
- using instance_type = T_instance;
-
- context_type& context;
- instance_type& instance;
- size_t split_count;
- size_t per_split;
-
- public:
- template<typename T_func>
- inline void for_subtasks(T_func&& func)
- {
- auto total_count = instance.subscribed_count();
-
- instance.prepare_states(split_count);
- utils::counter_blocker counter(split_count - 1);
-
- /* execute the splitted subtask */
- auto execute = [this, &func](size_t index, size_t from, size_t to)
- {
- auto data = data_proxy::make_multi(context, instance, index, from, to);
- func(data);
- };
-
- /* create subtasks */
- for (size_t i = 0; i < split_count - 1; ++i)
- {
- context.post_in_thread_pool([this, &counter, &execute, i](auto){
- ecs_make_scope_guard([&counter](){
- counter.decrement();
- });
- auto beg = i * per_split;
- auto end = (i + 1) * per_split;
- execute(i, beg, end);
- });
- }
-
- /* execute and wait */
- counter.execute_and_wait([this, &execute, total_count]{
- auto index = split_count - 1;
- auto beg = index * per_split;
- auto end = total_count;
- execute(index, beg, end);
- });
- }
- };
- };
-
- } } } }
|