tg_sync/
mutex.rs

1use super::UPIntrFreeCell;
2use alloc::collections::VecDeque;
3use tg_task_manage::ThreadId;
4
5/// Mutex trait
6pub trait Mutex: Sync + Send {
7    /// tid 表示的线程试图获取锁,并返回结果
8    fn lock(&self, tid: ThreadId) -> bool;
9    /// 当前线程释放锁,并唤醒某个阻塞在这个锁上的线程
10    fn unlock(&self) -> Option<ThreadId>;
11}
12
13/// MutexBlocking
14pub struct MutexBlocking {
15    inner: UPIntrFreeCell<MutexBlockingInner>,
16}
17
18/// MutexBlockingInner
19pub struct MutexBlockingInner {
20    locked: bool,
21    wait_queue: VecDeque<ThreadId>,
22}
23
24impl MutexBlocking {
25    /// 创建一个新的阻塞互斥锁。
26    pub fn new() -> Self {
27        Self {
28            // SAFETY: 此互斥锁仅在单处理器内核环境中使用
29            inner: unsafe {
30                UPIntrFreeCell::new(MutexBlockingInner {
31                    locked: false,
32                    wait_queue: VecDeque::new(),
33                })
34            },
35        }
36    }
37}
38
39impl Mutex for MutexBlocking {
40    // 获取锁,如果获取成功,返回 true,否则会返回 false,要求阻塞对应的线程
41    fn lock(&self, tid: ThreadId) -> bool {
42        let mut mutex_inner = self.inner.exclusive_access();
43        if mutex_inner.locked {
44            mutex_inner.wait_queue.push_back(tid);
45            drop(mutex_inner);
46            false
47        } else {
48            mutex_inner.locked = true;
49            true
50        }
51    }
52    // 释放锁,释放之后会唤醒一个被阻塞的进程,要求重新进入调度队列
53    fn unlock(&self) -> Option<ThreadId> {
54        let mut mutex_inner = self.inner.exclusive_access();
55        assert!(mutex_inner.locked);
56        if let Some(waking_task) = mutex_inner.wait_queue.pop_front() {
57            Some(waking_task)
58        } else {
59            mutex_inner.locked = false;
60            None
61        }
62    }
63}