use crate::sync::{Mutex, UPSafeCell}; use crate::task::{add_task, block_current_and_run_next, current_task, TaskControlBlock}; use alloc::{collections::VecDeque, sync::Arc}; pub struct Condvar { pub inner: UPSafeCell, } pub struct CondvarInner { pub wait_queue: VecDeque>, } impl Condvar { pub fn new() -> Self { Self { inner: unsafe { UPSafeCell::new(CondvarInner { wait_queue: VecDeque::new(), }) }, } } pub fn signal(&self) { let mut inner = self.inner.exclusive_access(); if let Some(task) = inner.wait_queue.pop_front() { add_task(task); } } pub fn wait(&self, mutex: Arc) { mutex.unlock(); let mut inner = self.inner.exclusive_access(); inner.wait_queue.push_back(current_task().unwrap()); drop(inner); block_current_and_run_next(); mutex.lock(); } }