/* * Scheduler.hpp * * Created on: 13 июл. 2019 г. * Author: titov */ #ifndef SOURCE_SYSTEMIC_SCHEDULER_HPP_ #define SOURCE_SYSTEMIC_SCHEDULER_HPP_ #include #include #include #include #include "IProcessor.hh" #include "../common/Result.hh" #include "../memories/allocator.hh" #include "../memories/instance_object.hpp" namespace systemic { typedef typename std::pair ProcessInfo; template 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 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 std::size_t systemic::Scheduler::proc_count = 0; template systemic::ProcessInfo * systemic::Scheduler::table = 0; template std::pmr::memory_resource * systemic::Scheduler::allocator = nullptr; template std::size_t systemic::Scheduler::size = 0; template float systemic::Scheduler::ts_in_second = 0.0f; template inline void systemic::Scheduler::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(*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 //inline Result< void, Error > systemic::Scheduler::runOnce() { inline void systemic::Scheduler::runOnce() { // FIXME Реализовать возвраты // 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 inline void systemic::Scheduler::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 inline systemic::SchedulerInterface::SchedulerInterface( ProcessInfo * table, std::size_t size, std::pmr::memory_resource * allocator ) { Scheduler::table = table; Scheduler::size = size; Scheduler::allocator = allocator; } template inline void systemic::SchedulerInterface::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_ */