1use super::UPSafeCell;
2use crate::task::TaskControlBlock;
3use crate::task::{block_current_and_run_next, suspend_current_and_run_next};
4use crate::task::{current_task, wakeup_task};
5use alloc::{collections::VecDeque, sync::Arc};
6
7pub trait Mutex: Sync + Send {
8 fn lock(&self);
9 fn unlock(&self);
10}
11
12pub struct MutexSpin {
13 locked: UPSafeCell<bool>,
14}
15
16impl MutexSpin {
17 pub fn new() -> Self {
18 Self {
19 locked: unsafe { UPSafeCell::new(false) },
20 }
21 }
22}
23
24impl Mutex for MutexSpin {
25 fn lock(&self) {
26 loop {
27 let mut locked = self.locked.exclusive_access();
28 if *locked {
29 drop(locked);
30 suspend_current_and_run_next();
31 continue;
32 } else {
33 *locked = true;
34 return;
35 }
36 }
37 }
38
39 fn unlock(&self) {
40 let mut locked = self.locked.exclusive_access();
41 *locked = false;
42 }
43}
44
45pub struct MutexBlocking {
46 inner: UPSafeCell<MutexBlockingInner>,
47}
48
49pub struct MutexBlockingInner {
50 locked: bool,
51 wait_queue: VecDeque<Arc<TaskControlBlock>>,
52}
53
54impl MutexBlocking {
55 pub fn new() -> Self {
56 Self {
57 inner: unsafe {
58 UPSafeCell::new(MutexBlockingInner {
59 locked: false,
60 wait_queue: VecDeque::new(),
61 })
62 },
63 }
64 }
65}
66
67impl Mutex for MutexBlocking {
68 fn lock(&self) {
69 let mut mutex_inner = self.inner.exclusive_access();
70 if mutex_inner.locked {
71 mutex_inner.wait_queue.push_back(current_task().unwrap());
72 drop(mutex_inner);
73 block_current_and_run_next();
74 } else {
75 mutex_inner.locked = true;
76 }
77 }
78
79 fn unlock(&self) {
80 let mut mutex_inner = self.inner.exclusive_access();
81 assert!(mutex_inner.locked);
82 if let Some(waking_task) = mutex_inner.wait_queue.pop_front() {
83 wakeup_task(waking_task);
84 } else {
85 mutex_inner.locked = false;
86 }
87 }
88}