#![no_std]
extern crate alloc;
pub use alloc::collections::{BTreeMap, BTreeSet};
pub type HashMap<K, V> = BTreeMap<K, V>;
pub type HashSet<T> = BTreeSet<T>;
mod task;
pub(crate) use task::*;
mod join;
pub use join::*;
mod waker;
pub use waker::*;
mod future;
pub use future::*;
mod runtime;
pub use runtime::*;
#[cfg(test)]
mod tests {
use super::*;
async fn foo(val: i32) -> i32 {
sched_yield().await;
val + 1
}
#[test]
fn test0() {
let mut rt = Runtime::new();
let _ = rt.spawn(foo(0));
let cnt = rt.sched();
assert_eq!(cnt, 1);
assert_eq!(rt.pending_count(), 0);
}
#[test]
fn test1() {
let mut rt = Runtime::new();
let h1 = rt.spawn(foo(0));
let h2 = rt.spawn(foo(1));
let cnt = rt.sched();
assert_eq!(h1.join(), Some(1));
assert_eq!(h2.join(), Some(2));
assert_eq!(cnt, 2);
assert_eq!(rt.pending_count(), 0);
}
async fn bar(val: i32) -> i32 {
*wait_event::<i32>(val as u64).await.unwrap()
}
#[test]
fn test2() {
let mut rt = Runtime::new();
let h = rt.spawn(bar(100));
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(h.is_finished(), false);
assert_eq!(rt.pending_count(), 1);
let cnt = rt.sched_events(&[Event::new(100, &200)]);
assert_eq!(cnt, 1);
assert_eq!(h.join(), Some(200));
assert_eq!(rt.pending_count(), 0);
}
#[test]
fn test3() {
let mut rt = Runtime::new();
let h = rt.spawn(bar(100));
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(h.is_finished(), false);
assert_eq!(rt.pending_count(), 1);
rt.notify_events(&[Event::new(100, &300)]);
let cnt = rt.sched();
assert_eq!(cnt, 1);
assert_eq!(h.join(), Some(300));
assert_eq!(rt.pending_count(), 0);
}
async fn boo(val: i32) -> i32 {
spawn(foo(val)).await.await.unwrap()
}
#[test]
fn test4() {
let mut rt = Runtime::new();
let h = rt.spawn(boo(99));
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 0);
assert_eq!(cnt, 2);
assert!(h.is_finished());
assert_eq!(h.join(), Some(100));
}
#[test]
fn test5() {
let mut rt = Runtime::new();
let h = rt.spawn(foo(1).and(foo(2)));
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 0);
assert_eq!(cnt, 1);
assert!(h.is_finished());
assert_eq!(h.join(), Some((2, 3)));
}
#[test]
fn test6() {
let mut rt = Runtime::new();
let h = rt.spawn(foo(1).or(foo(2)));
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 0);
assert_eq!(cnt, 1);
assert!(h.is_finished());
assert_eq!(h.join(), Some((Some(2), None)));
}
#[test]
fn test7() {
let mut rt = Runtime::new();
let h = rt.spawn(foo(1).partial_or(foo(2)));
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 0);
assert_eq!(cnt, 1);
assert!(h.is_finished());
assert_eq!(h.join(), Some((2, Some(3))));
}
#[test]
fn test8() {
let mut rt = Runtime::new();
let h = rt.spawn(foo(1).partial_or(foo(2)));
h.abort();
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 0);
assert_eq!(cnt, 0);
}
#[test]
fn test9() {
let mut rt = Runtime::new();
let h = rt.spawn(bar(10));
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 1);
assert_eq!(cnt, 0);
rt.notify_events(&[Event::new(10, &1)]);
h.abort();
let cnt = rt.sched();
assert_eq!(rt.pending_count(), 0);
assert_eq!(cnt, 1);
}
async fn join_set_wait_all(data: i32) {
let mut joinset = JoinSet::<i32>::new().await;
let id1 = joinset.spawn(foo(0));
let id2 = joinset.spawn(boo(1));
let id3 = joinset.spawn(bar(1));
for (task, val) in joinset.wait_all().await {
if task == id1 {
assert_eq!(val, Some(1));
} else if task == id2 {
assert_eq!(val, Some(2));
} else if task == id3 {
assert_eq!(val, Some(data));
} else {
assert!(false);
}
}
}
#[test]
fn test10() {
let mut rt = Runtime::new();
let _ = rt.spawn(join_set_wait_all(100));
let cnt = rt.sched();
assert_eq!(cnt, 3);
assert_eq!(rt.pending_count(), 2);
rt.notify_events(&[Event::new(1, &100)]);
let cnt = rt.sched();
assert_eq!(cnt, 2);
assert_eq!(rt.pending_count(), 0);
}
async fn join_set_wait_any(data: i32) {
let mut joinset = JoinSet::<i32>::new().await;
let id1 = joinset.spawn(foo(0));
let id2 = joinset.spawn(boo(1));
let id3 = joinset.spawn(bar(1));
while let Some((task, val)) = joinset.wait_any().await {
if task == id1 {
assert_eq!(val, Some(1));
} else if task == id2 {
assert_eq!(val, Some(2));
} else if task == id3 {
assert_eq!(val, Some(data));
} else {
assert!(false);
}
}
}
#[test]
fn test11() {
let mut rt = Runtime::new();
let _ = rt.spawn(join_set_wait_any(100));
let cnt = rt.sched();
assert_eq!(cnt, 3);
assert_eq!(rt.pending_count(), 2);
rt.notify_events(&[Event::new(1, &100)]);
let cnt = rt.sched();
assert_eq!(cnt, 2);
assert_eq!(rt.pending_count(), 0);
}
use core::cell::Cell;
use alloc::rc::Rc;
async fn suspend(id: Rc<Cell<u64>>) -> i32 {
id.set(task_self().await);
task_suspend().await;
100
}
#[test]
fn test12() {
let mut rt = Runtime::new();
let task_id = Rc::new(Cell::new(0_u64));
let h = rt.spawn(suspend(task_id.clone()));
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(rt.pending_count(), 1);
rt.task_resume(task_id.get());
let cnt = rt.sched();
assert_eq!(cnt, 1);
assert_eq!(rt.pending_count(), 0);
assert_eq!(h.join(), Some(100));
}
async fn foo_suspend(val: i32) -> i32 {
task_suspend().await;
val
}
#[test]
fn test13() {
let mut rt = Runtime::new();
let h = rt.spawn(foo_suspend(100));
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(rt.pending_count(), 1);
rt.task_force_abort(h.task_id());
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(rt.pending_count(), 0);
assert_eq!(h.is_finished(), true);
assert_eq!(h.is_aborted(), true);
assert_eq!(h.join(), None);
}
#[test]
fn test14() {
let mut rt = Runtime::new();
let h = rt.spawn(foo_suspend(100));
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(rt.pending_count(), 1);
async fn abort(task_id: u64) {
task_force_abort(task_id).await;
}
rt.spawn(abort(h.task_id()));
let cnt = rt.sched();
assert_eq!(cnt, 1);
assert_eq!(rt.pending_count(), 0);
assert_eq!(h.is_finished(), true);
assert_eq!(h.is_aborted(), true);
assert_eq!(h.join(), None);
}
async fn foo_join(val: i32, cnt: usize) -> i32{
let mut joinset = JoinSet::new().await;
for _ in 0..cnt {
let _ = joinset.spawn(foo_suspend(val));
}
let mut cnt = 0;
for (_, rlt) in joinset.wait_all().await {
cnt += rlt.unwrap_or(0);
}
cnt
}
#[test]
fn test15() {
let mut rt = Runtime::new();
let h = rt.spawn(foo_join(100, 2));
let cnt = rt.sched();
assert_eq!(cnt, 0);
assert_eq!(rt.pending_count(), 3);
async fn force_stop(id: u64) {
task_force_abort(id).await;
}
let _ = rt.spawn(force_stop(h.task_id()));
let cnt = rt.sched();
assert_eq!(cnt, 1);
assert_eq!(rt.pending_count(), 0);
}
}