126 lines
3.6 KiB
C
126 lines
3.6 KiB
C
|
#ifndef ALSK_ALSK_EXECUTOR_EXECUTORBASE_H
|
||
|
#define ALSK_ALSK_EXECUTOR_EXECUTORBASE_H
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <thread>
|
||
|
#include <tuple>
|
||
|
#include <utility>
|
||
|
#include <vector>
|
||
|
|
||
|
#include "tags.h"
|
||
|
#include "../impl/tags.h"
|
||
|
|
||
|
namespace alsk {
|
||
|
namespace exec {
|
||
|
|
||
|
struct ExecutorBase {
|
||
|
using IsExecutor = tag::Executor;
|
||
|
|
||
|
public:
|
||
|
struct Info {};
|
||
|
|
||
|
struct RCores {
|
||
|
std::vector<std::size_t> coresList;
|
||
|
|
||
|
RCores() { upTo(std::thread::hardware_concurrency()); }
|
||
|
|
||
|
/**
|
||
|
* @brief disables repeatability
|
||
|
*/
|
||
|
void disabled() noexcept { coresList.clear(); }
|
||
|
|
||
|
/**
|
||
|
* @brief defines possibles cores from min to n by given step
|
||
|
* @param n possibly included upper bound, if 0 or 1, disables repeatability
|
||
|
* @param min lower bound (at least 2, at most n)
|
||
|
* @param step step (at least 1)
|
||
|
*/
|
||
|
void upTo(std::size_t n, std::size_t min = 2, std::size_t step = 1) {
|
||
|
coresList.clear();
|
||
|
if(n < 2) return;
|
||
|
std::size_t k = (n-min+step) / step;
|
||
|
coresList.resize(k);
|
||
|
std::generate_n(std::begin(coresList), n-1, [i=0, &min, &step]() mutable { return (min+step*i++); });
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief defines possibles cores from min to n, multiplying by given step
|
||
|
* @param n possibly included upper bound, if 0 or 1, disables repeatability
|
||
|
* @param min lower bound (at least 2, at most n)
|
||
|
* @param step step (at least 2)
|
||
|
*/
|
||
|
void expUpTo(std::size_t n, std::size_t min = 2, std::size_t step = 2) {
|
||
|
coresList.clear();
|
||
|
if(n < 2) return;
|
||
|
while(min <= n) {
|
||
|
coresList.push_back(min);
|
||
|
min *= step;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief defines possibles cores from min to n, multiplying by given step
|
||
|
* @param args all cores to support
|
||
|
*/
|
||
|
template<typename... Args>
|
||
|
void forValues(Args&&... args) {
|
||
|
coresList = {std::forward<Args>(args)...};
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
/**
|
||
|
* @brief set this variable to the number of allotted cores
|
||
|
*/
|
||
|
std::size_t cores;
|
||
|
|
||
|
/**
|
||
|
* @brief this variable allows to configure repeatability
|
||
|
*/
|
||
|
RCores repeatability;
|
||
|
|
||
|
public:
|
||
|
ExecutorBase(): cores{std::thread::hardware_concurrency()} {}
|
||
|
|
||
|
public:
|
||
|
template<typename Impl>
|
||
|
void config(Impl&) {}
|
||
|
|
||
|
template<typename Impl>
|
||
|
std::size_t contextIdCount(Impl&, std::size_t id) { return id; }
|
||
|
|
||
|
template<typename Impl>
|
||
|
std::size_t contextId(Impl&, std::size_t id) { return id; }
|
||
|
|
||
|
template<typename Task, typename Impl, typename BTask, typename Parameters, typename Results, typename... Args>
|
||
|
decltype(auto) execute(Impl& impl, BTask& task, Parameters&& parameters, Results&& results, Args&&... args) {
|
||
|
return _execute<Task>(impl, task, impl.executorInfo, std::forward<Parameters>(parameters), std::forward<Results>(results),
|
||
|
std::forward<Args>(args)...);
|
||
|
}
|
||
|
|
||
|
template<typename Task, typename Impl, typename BTask, typename Parameters>
|
||
|
void executeSequential(Impl& impl, BTask& task, Parameters&& parameters, std::size_t n) {
|
||
|
return _executeSequential<Task>(impl, task, impl.executorInfo, std::forward<Parameters>(parameters), n);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
template<typename Task, typename Impl, typename BTask, typename Info, typename Parameters, typename Results, typename... Args>
|
||
|
decltype(auto) _execute(Impl& impl, BTask& task, Info&& info, Parameters&& parameters, Results&& results, Args&&... args) {
|
||
|
return Task::execute(
|
||
|
impl, task, 0, std::forward<Info>(info), std::forward<Parameters>(parameters), std::forward<Results>(results),
|
||
|
std::forward<Args>(args)...
|
||
|
);
|
||
|
}
|
||
|
|
||
|
template<typename Task, typename Impl, typename BTask, typename Info, typename Parameters>
|
||
|
void _executeSequential(Impl& impl, BTask& task, Info const& info, Parameters const& parameters, std::size_t n) {
|
||
|
for(std::size_t i = 0; i < n; ++i)
|
||
|
Task::execute(impl, task, i, info, parameters, std::tuple<>{});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|