[][src]Crate juggle

This crate provides a way to switch between tasks on single-thread or embedded environments utilizing cooperative multitasking.

It uses async/await mechanisms of Rust, tasks should have manual suspension points inside async functions to allow scheduler to switch them (see yield_once!() macro). Tasks can be dynamically created/cancelled/suspended/resumed and can await external events (e.g from other threads or interrupts) as any normal async functions. For more information about scheduler see Wheel.

Examples

Simple program that reads data from sensor and processes it.

use juggle::*;
use alloc::collections::VecDeque;
use core::cell::RefCell;

async fn collect_temperature(queue: &RefCell<VecDeque<i32>>,handle: WheelHandle<'_>){
    loop{ // loop forever or until cancelled
        let temperature: i32 = read_temperature_sensor().await;
        queue.borrow_mut().push_back(temperature);
        yield_once!(); // give scheduler opportunity to execute other tasks
    }
}

async fn wait_for_timer(id: IdNum,queue: &RefCell<VecDeque<i32>>,handle: WheelHandle<'_>){
    init_timer();
    for _ in 0..5 {
        yield_while!(get_timer_value() < 200); // busy wait but also executes other tasks.
        process_data(&mut queue.borrow_mut());
        reset_timer();
    }
    handle.cancel(id); // cancel 'collect_temperature' task.
    shutdown_timer();
}

fn main(){
    let queue = &RefCell::new(VecDeque::new());
    let wheel = Wheel::new();
    let handle = wheel.handle(); // handle to manage tasks, can be cloned inside this thread

    let temp_id = handle.spawn(SpawnParams::default(),
                               collect_temperature(queue,handle.clone()));
    handle.spawn(SpawnParams::default(),
                 wait_for_timer(temp_id.unwrap(),queue,handle.clone()));

    // execute tasks
    smol::block_on(wheel).unwrap(); // or any other utility to block on future.
}

Modules

utils

Couple of helpful utilities.

Macros

yield_once

Yield current task. Gives the scheduler opportunity to switch to another task. Equivalent to Yield::once().await.

yield_while

Yield current task until specific expression becomes false. Gives the scheduler opportunity to switch to another task.

Structs

IdNum

Represents identifier of task registered by WheelHandle.

LockedWheel

Same as Wheel except that it has fixed content and there is no way to control state of tasks within it. Implements Future.

SpawnParams

Parameters used when spawning task inside scheduler.

SuspendError

Error returned by scheduler's Future when all tasks become suspended.

Wheel

Single-thread async task scheduler with dynamic task state control. Implements Future.

WheelHandle

Handle used to spawn and control tasks in assigned Wheel. All tasks manipulation are done by this struct.

Yield

Helper struct for dealing with task switching.

Enums

State

Represents state of a task.

Functions

block_on

Utility for blocking on future with custom waker and pending action.

spin_block_on

Utility for busy blocking on future.