11#include "roo_collections.h"
12#include "roo_collections/flat_small_hash_set.h"
13#include "roo_threads.h"
14#include "roo_threads/condition_variable.h"
15#include "roo_threads/mutex.h"
39#ifndef ROO_SCHEDULER_IGNORE_PRIORITY
40#define ROO_SCHEDULER_IGNORE_PRIORITY 0
124 std::unique_ptr<Executable> task,
131#ifndef ROO_SCHEDULER_NO_DEPRECATED
151 std::unique_ptr<Executable> task,
156 std::function<
void()> task,
159#ifndef ROO_SCHEDULER_NO_DEPRECATED
173 return scheduleOn(roo_time::Uptime::Now(), task, priority);
182 return scheduleOn(roo_time::Uptime::Now(), std::move(task), priority);
188 return scheduleOn(roo_time::Uptime::Now(), std::move(task), priority);
197 int max_count = -1) {
240 bool empty()
const {
return queue_.empty(); }
266#if !ROO_SCHEDULER_IGNORE_PRIORITY
270 when_(roo_time::Uptime::Max()),
274 Entry(
ExecutionID id, Executable* task,
bool owns_task,
275 roo_time::Uptime when,
Priority priority)
280 owns_task_(owns_task) {}
286 priority_(other.priority_),
287 owns_task_(other.owns_task_) {
288 other.task_ =
nullptr;
289 other.owns_task_ =
false;
292 Entry& operator=(Entry&& other) {
293 if (
this == &other)
return *
this;
300 priority_ = other.priority_;
301 owns_task_ = other.owns_task_;
302 other.task_ =
nullptr;
303 other.owns_task_ =
false;
311 when_(roo_time::Uptime::Max()),
314 Entry(
ExecutionID id, Executable* task,
bool owns_task,
315 roo_time::Uptime when,
Priority priority)
316 : id_(id), task_(task), when_(when), owns_task_(owns_task) {}
322 owns_task_(other.owns_task_) {
323 other.owns_task_ =
false;
326 Entry& operator=(Entry&& other) {
327 if (
this == &other)
return *
this;
334 owns_task_ = other.owns_task_;
335 other.task_ =
nullptr;
336 other.owns_task_ =
false;
341 Entry(
const Entry& other) =
delete;
342 Entry& operator=(
const Entry& other) =
delete;
350 roo_time::Uptime when()
const {
return when_; }
351 Executable* task()
const {
return task_; }
355#if !ROO_SCHEDULER_IGNORE_PRIORITY
362 bool owns_task()
const {
return owns_task_; }
365 friend struct TimeComparator;
369 roo_time::Uptime when_;
371#if !ROO_SCHEDULER_IGNORE_PRIORITY
378 struct TimeComparator {
379 bool operator()(
const Entry& a,
const Entry& b) {
380 return a.when() > b.when() ||
381 (a.when() == b.when() && a.id() - b.id() > 0);
386 struct PriorityComparator {
387 bool operator()(
const Entry& a,
const Entry& b) {
388 return a.priority() < b.priority() ||
389 (a.priority() == b.priority() &&
390 (a.when() > b.when() ||
391 (a.when() == b.when() && a.id() - b.id() > 0)));
395 roo_time::Uptime getNearestExecutionTimeWithLockHeld()
const;
397 roo_time::Duration getNearestExecutionDelayWithLockHeld()
const;
399 ExecutionID push(roo_time::Uptime when, Executable* task,
bool owns_task,
405 bool runOneEligibleExecution(roo_time::Uptime deadline,
418 std::vector<Entry> queue_;
420#if !ROO_SCHEDULER_IGNORE_PRIORITY
422 std::vector<Entry> ready_;
433 roo_collections::FlatSmallHashSet<ExecutionID> canceled_;
435 mutable roo::mutex mutex_;
436 roo::condition_variable nonempty_;
442 Task(std::function<
void()> task) : task_(task) {}
446 std::function<void()> task_;
455 std::function<
void()> task,
458#ifndef ROO_SCHEDULER_NO_DEPRECATED
461 roo_time::Duration delay,
483 bool start(roo_time::Duration initial_delay);
495 std::function<void()> task_;
499 roo_time::Duration delay_;
508 std::function<
void()> task,
511#ifndef ROO_SCHEDULER_NO_DEPRECATED
522 bool start(roo_time::Uptime when = roo_time::Uptime::Now());
534 std::function<void()> task_;
538 roo_time::Duration period_;
539 roo_time::Uptime next_;
573 std::function<void()> task_;
587 std::function<
void()> done_cb = std::function<
void()>());
589 bool start(roo_time::Uptime when = roo_time::Uptime::Now());
603 std::function<void()> done_cb_;
Abstract interface for executable tasks in the scheduler queue.
virtual ~Executable()=default
virtual void execute(ExecutionID id)=0
virtual ~Iterator()=default
void execute(ExecutionID id) override
bool start(roo_time::Uptime when=roo_time::Uptime::Now())
Convenience adapter for periodic callable execution.
void execute(ExecutionID id) override
Priority priority() const
void setPriority(Priority priority)
bool start(roo_time::Uptime when=roo_time::Uptime::Now())
PeriodicTask(Scheduler &scheduler, std::function< void()> task, roo_time::Duration period, Priority priority=Priority::kNormal)
Convenience adapter for repetitive callable execution.
bool startInstantly()
Starts task immediately.
Priority priority() const
bool start()
Starts task using configured periodic delay.
RepetitiveTask(Scheduler &scheduler, std::function< void()> task, roo_time::Duration delay, Priority priority=Priority::kNormal)
void execute(ExecutionID id) override
void setPriority(Priority priority)
Schedules and dispatches delayed task executions.
bool executeEligibleTasksUpTo(roo_time::Uptime deadline, Priority min_priority=Priority::kMinimum, int max_count=-1)
Executes up to max_count eligible tasks due no later than deadline.
Scheduler()
Creates an empty scheduler.
ExecutionID scheduleNow(std::function< void()> task, Priority priority=Priority::kNormal)
Schedules callable execution as soon as possible.
ExecutionID scheduleAfter(Executable *task, roo_time::Duration delay, Priority priority=Priority::kNormal)
ExecutionID scheduleAfter(roo_time::Duration delay, Executable &task, Priority priority=Priority::kNormal)
Schedules execution after delay elapses.
void cancel(ExecutionID)
Marks execution identified by id as canceled.
void run()
Runs scheduler event loop forever.
ExecutionID scheduleNow(Executable &task, Priority priority=Priority::kNormal)
Schedules execution as soon as possible.
bool executeEligibleTasksUpToNow(Priority min_priority=Priority::kMinimum, int max_count=-1)
Executes up to max_count eligible tasks due no later than now.
void delay(roo_time::Duration delay, Priority min_priority=Priority::kNormal)
Delays for at least delay while executing scheduled work.
void delayUntil(roo_time::Uptime deadline, Priority min_priority=Priority::kNormal)
Delays until deadline while executing scheduled work.
roo_time::Uptime getNearestExecutionTime() const
Returns due time of the nearest upcoming execution.
roo_time::Duration getNearestExecutionDelay() const
Returns delay to the nearest upcoming execution.
void pruneCanceled()
Removes canceled executions from the queue.
bool executeEligibleTasks(int max_count=-1)
Executes up to max_count eligible tasks.
ExecutionID scheduleNow(std::unique_ptr< Executable > task, Priority priority=Priority::kNormal)
Schedules execution as soon as possible.
ExecutionID scheduleOn(roo_time::Uptime when, Executable &task, Priority priority=Priority::kNormal)
Schedules execution no earlier than when.
bool empty() const
Returns true iff no pending (non-canceled) executions exist.
bool executeEligibleTasks(Priority min_priority, int max_count=-1)
Executes up to max_count eligible tasks with at least min_priority.
ExecutionID scheduleOn(Executable *task, roo_time::Uptime when, Priority priority=Priority::kNormal)
Convenience adapter for cancelable and replaceable single pending work.
void scheduleAfter(roo_time::Duration delay, Priority priority=Priority::kNormal)
Schedules or reschedules task after delay.
bool is_scheduled() const
void scheduleNow(Priority priority=Priority::kNormal)
Schedules or reschedules task for immediate execution.
void execute(ExecutionID id) override
void scheduleOn(roo_time::Uptime when, Priority priority=Priority::kNormal)
Schedules or reschedules task at absolute time when.
Convenience adapter for one-time execution of an arbitrary callable.
Task(std::function< void()> task)
void execute(ExecutionID id) override
constexpr Priority PRIORITY_BACKGROUND
constexpr Priority PRIORITY_MINIMUM
constexpr Priority PRIORITY_CRITICAL
constexpr Priority PRIORITY_ELEVATED
constexpr Priority PRIORITY_MAXIMUM
ExecutionID EventID
Deprecated alias; prefer ExecutionID.
Priority
Priority controls dispatch order among eligible tasks.
constexpr Priority PRIORITY_NORMAL
constexpr Priority PRIORITY_REDUCED
constexpr Priority PRIORITY_SENSITIVE
int32_t ExecutionID
Represents a unique task execution identifier.