MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/systemic/Scheduler.hpp
2024-06-07 11:12:56 +03:00

199 lines
5.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Scheduler.hpp
*
* Created on: 13 июл. 2019 г.
* 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 Реализовать возвраты
// 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_ */