Refactored scheduler

This commit is contained in:
Pavel Kirienko
2014-03-08 13:03:04 +04:00
parent aef70367d9
commit 2fa3f2c7c7
5 changed files with 190 additions and 154 deletions
+52 -13
View File
@@ -4,26 +4,69 @@
#pragma once
#include <uavcan/timer.hpp>
#include <uavcan/internal/linked_list.hpp>
#include <uavcan/internal/transport/dispatcher.hpp>
namespace uavcan
{
class Scheduler;
class MonotonicDeadlineHandler : public LinkedListNode<MonotonicDeadlineHandler>, Noncopyable
{
uint64_t monotonic_deadline_;
protected:
Scheduler& scheduler_;
MonotonicDeadlineHandler(Scheduler& scheduler)
: monotonic_deadline_(0)
, scheduler_(scheduler)
{ }
virtual ~MonotonicDeadlineHandler() { stop(); }
public:
virtual void onMonotonicDeadline(uint64_t monotonic_timestamp) = 0;
void startWithDeadline(uint64_t monotonic_deadline);
void startWithDelay(uint64_t delay_usec);
void stop();
bool isRunning() const;
uint64_t getMonotonicDeadline() const { return monotonic_deadline_; }
};
class MonotonicDeadlineScheduler : Noncopyable
{
LinkedListRoot<MonotonicDeadlineHandler> handlers_; // Ordered by deadline, lowest first
public:
void add(MonotonicDeadlineHandler* mdh);
void remove(MonotonicDeadlineHandler* mdh);
bool doesExist(const MonotonicDeadlineHandler* mdh) const;
unsigned int getNumHandlers() const { return handlers_.getLength(); }
uint64_t pollAndGetMonotonicTimestamp(ISystemClock& sysclock);
uint64_t getEarliestDeadline() const;
};
class Scheduler : Noncopyable
{
enum { DefaultTimerResolutionMs = 5 };
enum { DefaultMonotonicDeadlineResolutionMs = 5 };
enum { DefaultCleanupPeriodMs = 1000 };
LinkedListRoot<TimerBase> ordered_timers_; // Ordered by deadline, lowest first
MonotonicDeadlineScheduler deadline_scheduler_;
Dispatcher dispatcher_;
uint64_t prev_cleanup_ts_;
uint64_t timer_resolution_;
uint64_t monotonic_deadline_resolution_;
uint64_t cleanup_period_;
uint64_t computeDispatcherSpinDeadline(uint64_t spin_deadline) const;
uint64_t pollTimersAndGetMonotonicTimestamp();
void pollCleanup(uint64_t mono_ts, uint32_t num_frames_processed_with_last_spin);
public:
@@ -31,25 +74,21 @@ public:
NodeID self_node_id)
: dispatcher_(can_driver, allocator, sysclock, otr, self_node_id)
, prev_cleanup_ts_(sysclock.getMonotonicMicroseconds())
, timer_resolution_(DefaultTimerResolutionMs * 1000)
, monotonic_deadline_resolution_(DefaultMonotonicDeadlineResolutionMs * 1000)
, cleanup_period_(DefaultCleanupPeriodMs * 1000)
{ }
int spin(uint64_t monotonic_deadline);
void registerOneShotTimer(TimerBase* timer);
void unregisterOneShotTimer(TimerBase* timer);
bool isOneShotTimerRegistered(const TimerBase* timer) const;
unsigned int getNumOneShotTimers() const { return ordered_timers_.getLength(); }
MonotonicDeadlineScheduler& getMonotonicDeadlineScheduler() { return deadline_scheduler_; }
Dispatcher& getDispatcher() { return dispatcher_; }
ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); }
uint64_t getMonotonicTimestamp() const { return dispatcher_.getSystemClock().getMonotonicMicroseconds(); }
uint64_t getUtcTimestamp() const { return dispatcher_.getSystemClock().getUtcMicroseconds(); }
uint64_t getTimerResolution() const { return timer_resolution_; }
void setTimerResolution(uint64_t res_usec) { timer_resolution_ = res_usec; }
uint64_t getMonotonicDeadlineResolution() const { return monotonic_deadline_resolution_; }
void setMonotonicDeadlineResolution(uint64_t res_usec) { monotonic_deadline_resolution_ = res_usec; }
uint64_t getCleanupPeriod() const { return cleanup_period_; }
void setCleanupPeriod(uint64_t period_usec) { cleanup_period_ = period_usec; }
+20 -29
View File
@@ -5,80 +5,71 @@
#pragma once
#include <stdint.h>
#include <uavcan/scheduler.hpp>
#include <uavcan/internal/util.hpp>
#include <uavcan/internal/linked_list.hpp>
namespace uavcan
{
class Scheduler;
class TimerBase;
class Timer;
struct TimerEvent
{
uint64_t scheduled_monotonic_deadline;
uint64_t monotonic_timestamp;
TimerBase* timer;
Timer* timer;
TimerEvent(uint64_t scheduled_monotonic_deadline, uint64_t monotonic_timestamp, TimerBase& timer)
TimerEvent(Timer* timer, uint64_t scheduled_monotonic_deadline, uint64_t monotonic_timestamp)
: scheduled_monotonic_deadline(scheduled_monotonic_deadline)
, monotonic_timestamp(monotonic_timestamp)
, timer(&timer)
, timer(timer)
{ }
};
class TimerBase : public LinkedListNode<TimerBase>, Noncopyable
class Timer : private MonotonicDeadlineHandler
{
friend class Scheduler;
uint64_t monotonic_deadline_;
uint64_t period_;
Scheduler& scheduler_;
void handleOneShotTimeout(uint64_t ts_monotonic);
void genericStart();
void onMonotonicDeadline(uint64_t monotonic_timestamp);
public:
static const uint64_t InfinitePeriod = 0xFFFFFFFFFFFFFFFFUL;
TimerBase(Scheduler& scheduler)
: monotonic_deadline_(0)
using MonotonicDeadlineHandler::stop;
using MonotonicDeadlineHandler::isRunning;
using MonotonicDeadlineHandler::getMonotonicDeadline;
Timer(Scheduler& scheduler)
: MonotonicDeadlineHandler(scheduler)
, period_(InfinitePeriod)
, scheduler_(scheduler)
{ }
virtual ~TimerBase() { stop(); }
uint64_t getMonotonicDeadline() const { return monotonic_deadline_; }
void startOneShotDeadline(uint64_t monotonic_deadline_usec);
void startOneShotDelay(uint64_t delay_usec);
void startOneShotWithDeadline(uint64_t monotonic_deadline);
void startOneShotWithDelay(uint64_t delay_usec);
void startPeriodic(uint64_t period_usec);
void stop();
bool isRunning() const;
uint64_t getPeriod() const { return period_; }
virtual void onTimerEvent(TimerEvent& event) = 0;
virtual void onTimerEvent(const TimerEvent& event) = 0;
};
template <typename Functor>
class Timer : public TimerBase
class TimerEventForwarder : public Timer
{
Functor functor_;
public:
Timer(Scheduler& node, Functor functor)
: TimerBase(node)
TimerEventForwarder(Scheduler& node, Functor functor)
: Timer(node)
, functor_(functor)
{ }
const Functor& getFunctor() const { return functor_; }
void onTimerEvent(TimerEvent& event)
void onTimerEvent(const TimerEvent& event)
{
functor_(event);
}