Skip to content

[RFC] Add API to re-schedule & cancel tasks #7

Closed
@korken89

Description

@korken89

Summary

Add support for re-scheduling and canceling scheduled tasks.

Current behavior

Today there is no way to re-schedule or cancel scheduled tasks as:

#[rtfm::app]
const APP: () = {
    #[task(schedule = [timeout])]
    fn task(cx: task::Context) {
        // ... some work that needs timeout

        cx.schedule.timeout(SOME_TIME).unwrap();
        // ^^^ There is no way to make this re-schedule or cancel today
        // without an external resource and working around RTFM
    }

    #[task]
    fn timeout(cx: timeout::Context) {
        // Does the work if there was a timeout ...
    }
};

Proposal

Add an API to be able to re-schedule and cancel a scheduled task. This is something that also has been requested verbally and officially in rtfm-rs/cortex-m-rtfm#220, and is a sane feature. Creating watchdog & timeout tasks or scheduling on incomplete information is tricky today and needs working around RTFM.

Proposed syntax

For re-scheduling there are 2 options:

#[rtfm::app]
const APP: () = {
    #[task(schedule = [timeout])]
    fn task(cx: task::Context) {
        // ... some work that needs timeout

        // Option 1:
        cx.schedule.timeout(SOME_TIME).unwrap();
        // ^^^ This automatically re-schedules

        // Option 2: Add a specific API 
        cx.reschedule.timeout(SOME_TIME).unwrap();
    }

    #[task]
    fn timeout(cx: timeout::Context) {
        // Does the work if there was a timeout ...
    }
};

Here a Result should be return telling if the task was rescheduled (Ok), or if the task has already been pended for execution (Err).

And for canceling, the straight forward syntax as follows:

#[rtfm::app]
const APP: () = {
    #[task(schedule = [timeout])]
    fn task(cx: task::Context) {
        // ... some work that needs timeout
        cx.schedule.timeout(SOME_TIME).unwrap();

        // decide that we want to cancel the scheduled task
        cx.cancel.timeout().unwrap();
    }

    #[task]
    fn timeout(cx: timeout::Context) {
        // Does the work if there was a timeout ...
    }
};

Also here a Result should be return telling if the task was canceled (Ok), or if the task has already been started/executed (Err).

Not in scope

  • This proposal is for tasks with capacity of 1. Rescheduling and canceling task that have capacity would be a future extension if need arises.

Issues to tackle

  1. The schedule list probably becomes an O(n) list instead of using the binary heap we have today This can most likely be solved by running sift up/down.
  2. Bike-shed the API
  3. More concerns?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions