miniloop

Crates.iominiloop
lib.rsminiloop
version
sourcesrc
created_at2024-11-14 22:59:28.026298
updated_at2024-12-24 09:16:13.279877
descriptionThe simpliest async executor without heap memory allocation
homepage
repositoryhttps://github.com/vpetrigo/sntpc
max_upload_size
id1448413
Cargo.toml error:TOML parse error at line 22, column 1 | 22 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Vladimir Petrigo (vpetrigo)

documentation

README

build Crates.io Version

miniloop - simple asynchronous executor

This repository is created as an attempt to clarify some more low-level details about how things work in Rust asynchronous world.

The miniloop executor creates a statically allocated list of tasks. That number should be available upon a crate build:

  • MINILOOP_TASK_ARRAY_SIZE: default value is 1 which means you can schedule a single task within the executor. To override that just define an environment variable with the number of tasks you plan to use in your application.

Configuration

You can set up the environment variable in a shell prior to running the cargo build command:

  • Linux
    export MINILOOP_TASK_ARRAY_SIZE=10
    
  • Windows
    $env:MINILOOP_TASK_ARRAY_SIZE = 10
    

Or you can use configurable environment feature by creating a .cargo/config.toml file with the following content:

[env]
MINILOOP_TASK_ARRAY_SIZE = "10"

miniloop in action

Create your tasks on the stack, add them to the executor and enjoy!

use miniloop::executor::Executor;
use miniloop::helpers::yield_me;
use miniloop::task::Task;

fn sleep(s: u64) {
  std::thread::sleep(std::time::Duration::from_secs(s));
}

async fn dummy_func(data: &str) {
  const TICKS: usize = 4;
  let mut counter = 0usize;

  while counter != TICKS {
    sleep(2);
    let now = get_timestamp_sec();
    println!("{now}: {data}");
    yield_me().await;
    counter += 1;
  }
}

fn get_timestamp_sec() -> u64 {
  std::time::SystemTime::now()
          .duration_since(std::time::UNIX_EPOCH)
          .unwrap()
          .as_secs()
}

fn pending_print(task_name: &str) {
  let now = get_timestamp_sec();
  println!("{now}: Task {task_name} is pending. Waiting for the next tick...");
}

fn main() {
    let mut executor = Executor::new();
    executor.set_pending_callback(pending_print);

    let mut task1 = Task::new("hello", async {
        dummy_func("hello").await;
    });
    let mut handle1 = task1.create_handle();
    let mut task2 = Task::new("world", async {
        dummy_func("world").await;
    });
    let mut handle2 = task2.create_handle();

    let _ = executor.spawn(&mut task1, &mut handle1);
    let _ = executor.spawn(&mut task2, &mut handle2);

    executor.run();
    println!("Done!");
    assert!(handle1.value.is_some());
    assert!(handle2.value.is_some());
}

License

This project is licensed under Apache License, Version 2.0
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in time by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.
Commit count: 326

cargo fmt