Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UAVCAN UAVCAN_Subscriber
scheduler.hpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #ifndef UAVCAN_NODE_SCHEDULER_HPP_INCLUDED 00006 #define UAVCAN_NODE_SCHEDULER_HPP_INCLUDED 00007 00008 #include <uavcan/error.hpp> 00009 #include <uavcan/util/linked_list.hpp> 00010 #include <uavcan/transport/dispatcher.hpp> 00011 00012 namespace uavcan 00013 { 00014 00015 class UAVCAN_EXPORT Scheduler; 00016 00017 class UAVCAN_EXPORT DeadlineHandler : public LinkedListNode<DeadlineHandler> 00018 { 00019 MonotonicTime deadline_; 00020 00021 protected: 00022 Scheduler& scheduler_; 00023 00024 explicit DeadlineHandler(Scheduler& scheduler) 00025 : scheduler_(scheduler) 00026 { } 00027 00028 virtual ~DeadlineHandler() { stop(); } 00029 00030 public: 00031 virtual void handleDeadline(MonotonicTime current) = 0; 00032 00033 void startWithDeadline(MonotonicTime deadline); 00034 void startWithDelay(MonotonicDuration delay); 00035 void generateDeadlineImmediately() { startWithDeadline(MonotonicTime::fromUSec(1)); } 00036 00037 void stop(); 00038 00039 bool isRunning() const; 00040 00041 MonotonicTime getDeadline() const { return deadline_; } 00042 Scheduler& getScheduler() const { return scheduler_; } 00043 }; 00044 00045 00046 class UAVCAN_EXPORT DeadlineScheduler : Noncopyable 00047 { 00048 LinkedListRoot<DeadlineHandler> handlers_; // Ordered by deadline, lowest first 00049 00050 public: 00051 void add(DeadlineHandler* mdh); 00052 void remove(DeadlineHandler* mdh); 00053 bool doesExist(const DeadlineHandler* mdh) const; 00054 unsigned getNumHandlers() const { return handlers_.getLength(); } 00055 00056 MonotonicTime pollAndGetMonotonicTime(ISystemClock& sysclock); 00057 MonotonicTime getEarliestDeadline() const; 00058 }; 00059 00060 /** 00061 * This class distributes processing time between library components (IO handling, deadline callbacks, ...). 00062 */ 00063 class UAVCAN_EXPORT Scheduler : Noncopyable 00064 { 00065 enum { DefaultDeadlineResolutionMs = 5 }; 00066 enum { MinDeadlineResolutionMs = 1 }; 00067 enum { MaxDeadlineResolutionMs = 100 }; 00068 00069 enum { DefaultCleanupPeriodMs = 1000 }; 00070 enum { MinCleanupPeriodMs = 10 }; 00071 enum { MaxCleanupPeriodMs = 10000 }; 00072 00073 DeadlineScheduler deadline_scheduler_; 00074 Dispatcher dispatcher_; 00075 MonotonicTime prev_cleanup_ts_; 00076 MonotonicDuration deadline_resolution_; 00077 MonotonicDuration cleanup_period_; 00078 bool inside_spin_; 00079 00080 struct InsideSpinSetter 00081 { 00082 Scheduler& owner; 00083 InsideSpinSetter(Scheduler& o) 00084 : owner(o) 00085 { 00086 owner.inside_spin_ = true; 00087 } 00088 ~InsideSpinSetter() { owner.inside_spin_ = false; } 00089 }; 00090 00091 MonotonicTime computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const; 00092 void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin); 00093 00094 public: 00095 Scheduler(ICanDriver& can_driver, IPoolAllocator& allocator, ISystemClock& sysclock) 00096 : dispatcher_(can_driver, allocator, sysclock) 00097 , prev_cleanup_ts_(sysclock.getMonotonic()) 00098 , deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs)) 00099 , cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs)) 00100 , inside_spin_(false) 00101 { } 00102 00103 /** 00104 * Spin until the deadline, or until some error occurs. 00105 * This function will return strictly when the deadline is reached, even if there are unprocessed frames. 00106 * Returns negative error code. 00107 */ 00108 int spin(MonotonicTime deadline); 00109 00110 /** 00111 * Non-blocking version of @ref spin() - spins until all pending frames and events are processed, 00112 * or until some error occurs. If there's nothing to do, returns immediately. 00113 * Returns negative error code. 00114 */ 00115 int spinOnce(); 00116 00117 DeadlineScheduler& getDeadlineScheduler() { return deadline_scheduler_; } 00118 00119 Dispatcher& getDispatcher() { return dispatcher_; } 00120 const Dispatcher& getDispatcher() const { return dispatcher_; } 00121 00122 ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); } 00123 MonotonicTime getMonotonicTime() const { return dispatcher_.getSystemClock().getMonotonic(); } 00124 UtcTime getUtcTime() const { return dispatcher_.getSystemClock().getUtc(); } 00125 00126 /** 00127 * Worst case deadline callback resolution. 00128 * Higher resolution increases CPU usage. 00129 */ 00130 MonotonicDuration getDeadlineResolution() const { return deadline_resolution_; } 00131 void setDeadlineResolution(MonotonicDuration res) 00132 { 00133 res = min(res, MonotonicDuration::fromMSec(MaxDeadlineResolutionMs)); 00134 res = max(res, MonotonicDuration::fromMSec(MinDeadlineResolutionMs)); 00135 deadline_resolution_ = res; 00136 } 00137 00138 /** 00139 * How often the scheduler will run cleanup (listeners, outgoing transfer registry, ...). 00140 * Cleanup execution time grows linearly with number of listeners and number of items 00141 * in the Outgoing Transfer ID registry. 00142 * Lower period increases CPU usage. 00143 */ 00144 MonotonicDuration getCleanupPeriod() const { return cleanup_period_; } 00145 void setCleanupPeriod(MonotonicDuration period) 00146 { 00147 period = min(period, MonotonicDuration::fromMSec(MaxCleanupPeriodMs)); 00148 period = max(period, MonotonicDuration::fromMSec(MinCleanupPeriodMs)); 00149 cleanup_period_ = period; 00150 } 00151 }; 00152 00153 } 00154 00155 #endif // UAVCAN_NODE_SCHEDULER_HPP_INCLUDED
Generated on Tue Jul 12 2022 17:17:34 by
1.7.2