85 #ifndef SRC_VAULT_GEAR_LOAD_CONTROLLER_H_ 86 #define SRC_VAULT_GEAR_LOAD_CONTROLLER_H_ 102 #include <functional> 119 using std::chrono_literals::operator
""ms;
120 using std::chrono_literals::operator
""us;
122 using std::atomic_int64_t;
123 using std::memory_order_relaxed;
128 _uTicks (std::chrono::microseconds us)
158 function<size_t()> maxCapacity {[]{
return 1; }};
159 function<size_t()> currWorkForceSize{[]{
return 0; }};
160 function<void(uint)> stepUpWorkForce{[](uint){}};
166 : wiring_{std::move (wiring)}
179 atomic_int64_t sampledLag_{0};
192 double lag = _raw(std::clamp<TimeVar> (now - (head.
isRegular()? head:now)
196 int64_t average = sampledLag_.load (memory_order_relaxed);
198 do newAverage = std::floor (lag*alpha + (1-alpha)*average);
199 while (not sampledLag_.compare_exchange_weak (average, newAverage, memory_order_relaxed));
214 return sampledLag_.load (memory_order_relaxed);
226 return sampledLag_.exchange(lag, memory_order_relaxed);
243 double lagFactor = lag<0? 1/(1-lag): 1+lag;
244 double loadFactor = wiring_.currWorkForceSize() / double(wiring_.maxCapacity());
245 return loadFactor * lagFactor;
256 wiring_.stepUpWorkForce(+4);
259 wiring_.stepUpWorkForce(+1);
278 wiring_.stepUpWorkForce(+1);
289 or nextHead == tendedHead_;
302 tendedHead_ = nextHead;
323 if (off > Time::ZERO)
return SPINTIME;
371 auto scatter = [&](
Duration horizon)
373 gavl_time_t wrap = hash_value(now) % _raw(horizon);
374 ENSURE (0 <= wrap and wrap < _raw(horizon));
378 TimeVar headDistance = max (tendedHead_-now, Time::ZERO);
386 return Offset{headDistance};
393 NOTREACHED (
"uncovered work capacity classification.");
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
bool tendedNext(Time nextHead) const
did we already tend for the indicated next relevant head time?
int64_t setCurrentAverageLag(int64_t lag)
a mutable time value, behaving like a plain number, allowing copy and re-accessing ...
Duration NEAR_HORIZON
what counts as "imminent" (e.g. for spin-waiting)
void markLagSample(Time head, Time now)
const double LAG_SAMPLE_DAMPING
smoothing factor for exponential moving average of lag;
Any copy and copy construction prohibited.
double effectiveLoad() const
Capacity markIncomingCapacity(Time head, Time now)
decide how this thread's capacity shall be used when returning from idle wait and asking for work ...
Lumiera's internal time value datatype.
Controller to coordinate resource usage related to the Scheduler.
void ensureCapacity(Time startHorizon)
Hook to check and possibly scale up WorkForce to handle one additional job.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
capacity for active processing required
Offset scatteredDelayTime(Time now, Capacity capacity)
Generate a time offset to relocate currently unused capacity to a time range where it's likely to be ...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Duration STANDARD_LAG
Experience shows that on average scheduling happens with 200µs delay.
boost::rational< int64_t > FSecs
rational representation of fractional seconds
void tendNext(Time nextHead)
Mark the indicated next head time as tended.
Lumiera error handling (C++ interface).
void markWorkerExit()
statistics update on scaling down the WorkForce
Duration SLEEP_HORIZON
schedules beyond that horizon justify going idle
Offset measures a distance in time.
awaiting imminent activities
int64_t averageLag() const
Duration is the internal Lumiera time metric.
NUM constexpr limited(NB lowerBound, NUM val, NB upperBound)
force a numeric to be within bounds, inclusively
static Capacity classifyTimeHorizon(Offset off)
classification of time horizon for scheduling
Capacity markOutgoingCapacity(Time head, Time now)
decide how this thread's capacity shall be used after it returned from being actively employed ...
Duration WORK_HORIZON
the scope of activity currently in the works
basic constant internal time value.
Capacity
Allocation of capacity to time horizon of expected work.
Vault-Layer implementation namespace root.
void updateState(Time)
periodic call to build integrated state indicators
typical stable work task rhythm expected