MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/systemic/Scheduler.hpp

199 lines
5.0 KiB
C++
Raw Normal View History

/*
* Scheduler.hpp
*
* Created on: 13 <EFBFBD><EFBFBD><EFBFBD>. 2019 <EFBFBD>.
* Author: titov
*/
#ifndef SOURCE_SYSTEMIC_SCHEDULER_HPP_
#define SOURCE_SYSTEMIC_SCHEDULER_HPP_
#include <utility>
#include <cstddef>
#include <stdexcept>
#include <memory_resource>
#include "IProcessor.hh"
#include "../common/Result.hh"
#include "../memories/allocator.hh"
#include "../memories/instance_object.hpp"
namespace systemic {
typedef typename std::pair<systemic::IProcess *, systemic::IProcessor::Priority> ProcessInfo;
template<unsigned tag_id>
struct Scheduler {
static const unsigned tag = tag_id;
typedef IProcessor::Priority Priority;
typedef IProcessor::Period Period;
typedef IProcessor::Phase Phase;
typedef IProcessor::Controlled Controlled;
// static Result< void, Error > runOnce();
static void runOnce();
static void setSampleTime( float ts_in_second );
protected:
static ProcessInfo * table;
static std::size_t size;
static std::pmr::memory_resource * allocator;
static void reqisterProcess( Priority priority, Period period, Phase phase, Controlled controlled, IProcess & proc );
static float ts_in_second;
static std::size_t proc_count;
};
template<typename Scheduler>
struct SchedulerInterface : public IProcessor, public Scheduler {
typedef unsigned Tag;
static const Tag tag = Scheduler::tag;
std::size_t count_proc = 0;
SchedulerInterface( ProcessInfo * table,
std::size_t size,
std::pmr::memory_resource * allocator = std::pmr::get_default_resource() );
void reqisterProcess( Priority priority, Period period, Phase phase, Controlled controlled, IProcess & proc );
};
struct SparseProcess : public IProcess {
const IProcessor::Period period;
IProcessor::Period counter;
IProcess & proc;
SparseProcess( IProcessor::Period period, IProcess & proc );
void process();
};
}
template<unsigned tag_id>
std::size_t systemic::Scheduler<tag_id>::proc_count = 0;
template<unsigned tag_id>
systemic::ProcessInfo * systemic::Scheduler<tag_id>::table = 0;
template<unsigned tag_id>
std::pmr::memory_resource * systemic::Scheduler<tag_id>::allocator = nullptr;
template<unsigned tag_id>
std::size_t systemic::Scheduler<tag_id>::size = 0;
template<unsigned tag_id>
float systemic::Scheduler<tag_id>::ts_in_second = 0.0f;
template<unsigned tag_id>
inline void systemic::Scheduler<tag_id>::reqisterProcess(
Priority priority, Period period, Phase phase, Controlled controlled,
IProcess & proc ) {
if( proc_count < size ) {
IProcess * proc_interface = &proc;
if( allocator and period )
proc_interface = ::memories::instance_object<SparseProcess>(*allocator, period, proc);
table[proc_count] = std::make_pair( proc_interface, priority );
for( std::size_t i = proc_count; i > 0; i-- )
if( table[i-1].second > priority )
std::swap(table[i], table[i-1]);
proc_count++;
proc.setSampleTime( period ? period * ts_in_second : ts_in_second );
}
}
template<unsigned tag_id>
//inline Result< void, Error > systemic::Scheduler<tag_id>::runOnce() {
inline void systemic::Scheduler<tag_id>::runOnce() {
// FIXME <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// typedef Result< void, Error > Result;
for( std::size_t j = 0; j < proc_count; ++j ) {
systemic::IProcess * proc = table[j].first;
if ( proc == nullptr ) continue;
proc->process();
//#if __cplusplus >= 201103L
// if ( status.isErr() ) {
// table[j].first = nullptr;
// return Result(std::move(status));
// }
//#else
// if ( status.isErr() ) {
// table[j].first = nullptr;
// return Result(status);
// }
//#endif
}
}
template<unsigned tag_id>
inline void systemic::Scheduler<tag_id>::setSampleTime( float sample_time ) {
if( ts_in_second != sample_time ) {
ts_in_second = sample_time;
for( std::size_t j = 0; j < proc_count; ++j )
table[j].first->setSampleTime( ts_in_second );
}
}
template<typename Scheduler>
inline systemic::SchedulerInterface<Scheduler>::SchedulerInterface(
ProcessInfo * table, std::size_t size, std::pmr::memory_resource * allocator ) {
Scheduler::table = table;
Scheduler::size = size;
Scheduler::allocator = allocator;
}
template<typename Scheduler>
inline void systemic::SchedulerInterface<Scheduler>::reqisterProcess(
Priority priority, Period period, Phase phase, Controlled controlled,
IProcess & proc ) {
count_proc++;
Scheduler::reqisterProcess(priority, period, phase, controlled, proc);
}
inline systemic::SparseProcess::SparseProcess(IProcessor::Period period,
IProcess & proc ) : proc(proc), period(period), counter(0) {}
inline void systemic::SparseProcess::process() {
if( ++counter == period ) {
counter = 0;
proc.process();
}
}
#endif /* SOURCE_SYSTEMIC_SCHEDULER_HPP_ */