#![no_implicit_prelude]
use ::drone_core::{
thr,
thr::{pending_size, SoftThrToken, SoftThread, ThrExec, PRIORITY_LEVELS},
token::Token,
};
use ::std::{
assert_eq,
clone::Clone,
sync::{atomic::Ordering, Arc, Mutex},
vec::Vec,
};
#[test]
fn test_set_pending() {
thr::soft! {
thread => Thr {};
local => ThrLocal {};
index => Thrs;
threads => {};
set_pending => set_pending;
}
unsafe fn set_pending(thr_idx: u16) {
if Thr::will_preempt(thr_idx) {
Thr::preempt();
}
}
}
#[test]
fn test_resume() {
thr::soft! {
thread => Thr {};
local => ThrLocal {};
index => Thrs;
threads => {};
resume => resume;
}
unsafe fn resume(thr: &Thr) {
use ::drone_core::thr::prelude::*;
thr.fib_chain().drain();
}
}
#[test]
fn test_pending_size() {
thr::soft! {
thread => Thr0 {};
local => ThrLocal0 {};
index => Thrs0;
threads => {};
}
thr::soft! {
thread => Thr32 {};
local => ThrLocal32 {};
index => Thrs32;
threads => {
a0; a1; a2; a3; a4; a5; a6; a7; a8; a9; a10; a11; a12; a13; a14;
a15; a16; a17; a18; a19; a20; a21; a22; a23; a24; a25; a26; a27;
a28; a29; a30; a31;
};
}
thr::soft! {
thread => Thr33 {};
local => ThrLocal33 {};
index => Thrs33;
threads => {
b0; b1; b2; b3; b4; b5; b6; b7; b8; b9; b10; b11; b12; b13; b14;
b15; b16; b17; b18; b19; b20; b21; b22; b23; b24; b25; b26; b27;
b28; b29; b30; b31; b32;
};
}
assert_eq!(pending_size::<Thr0>(), 1 + 0 * PRIORITY_LEVELS as usize);
assert_eq!(pending_size::<Thr32>(), 1 + 1 * PRIORITY_LEVELS as usize);
assert_eq!(pending_size::<Thr33>(), 1 + 2 * PRIORITY_LEVELS as usize);
}
#[test]
fn test_priorities() {
thr::soft! {
thread => Thr {};
local => ThrLocal {};
index => Thrs;
threads => { thr_0; thr_1; thr_2; };
}
let Thrs { thr_0, thr_1, thr_2 } = unsafe { Thrs::take() };
let log = Arc::new(Mutex::new(Vec::new()));
let log_0 = Arc::clone(&log);
let log_1 = Arc::clone(&log);
let log_2 = Arc::clone(&log);
thr_0.set_priority(0);
thr_1.set_priority(1);
thr_2.set_priority(2);
thr_0.add_exec(async move {
log_0.lock().unwrap().push(0);
thr_2.wakeup();
log_0.lock().unwrap().push(1);
});
thr_1.add_exec(async move {
log_1.lock().unwrap().push(2);
});
thr_2.add_exec(async move {
log_2.lock().unwrap().push(3);
thr_1.wakeup();
log_2.lock().unwrap().push(4);
});
thr_0.wakeup();
assert_eq!(*log.lock().unwrap(), &[0, 3, 4, 2, 1]);
assert_eq!(unsafe { &*Thr::pending_priority() }.load(Ordering::Relaxed), 0);
for i in 0..pending_size::<Thr>() {
assert_eq!(unsafe { &*Thr::pending().add(i) }.load(Ordering::Relaxed), 0);
}
}