199 lines
5.0 KiB
C++
199 lines
5.0 KiB
C++
|
|
/*
|
|||
|
|
* 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_ */
|