39 lines
1,017 B
Rust
39 lines
1,017 B
Rust
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<CondvarInner>,
|
|
}
|
|
|
|
pub struct CondvarInner {
|
|
pub wait_queue: VecDeque<Arc<TaskControlBlock>>,
|
|
}
|
|
|
|
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<dyn Mutex>) {
|
|
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();
|
|
}
|
|
}
|