use avr_oxide::concurrency::util::ThreadSet;
use avr_oxide::concurrency::{scheduler,interrupt};
use avr_oxide::concurrency::scheduler::ThreadState;
use avr_oxide::thread;
pub struct EventWait {
blocked_threads: ThreadSet
}
impl EventWait {
pub fn new() -> Self {
EventWait {
blocked_threads: ThreadSet::new()
}
}
pub fn wait(&mut self) {
interrupt::isolated(|isotoken|{
self.add_to_waitlist(isotoken);
});
thread::yield_now();
}
pub fn add_to_waitlist(&mut self, isotoken: interrupt::token::Isolated) {
self.blocked_threads.add_current_thread(isotoken);
scheduler::set_current_thread_state(isotoken, ThreadState::BlockedOnEvent);
}
pub fn release_one(&mut self) {
self.release(1)
}
pub fn release_all(&mut self) {
self.release(avr_oxide::deviceconsts::oxide::MAX_THREADS)
}
pub fn release(&mut self, mut count: usize) {
interrupt::isolated(|isotoken|{
self.blocked_threads.do_each_consuming(isotoken, |isotoken,thread_id|{
if scheduler::try_set_thread_state(isotoken, thread_id, ThreadState::Schedulable).is_ok() {
count -= 1;
}
count != 0
});
})
}
}