Skip to main content

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            // 已被占用:把线程放入等待队列,交由调度器阻塞当前线程。
45            mutex_inner.wait_queue.push_back(tid);
46            drop(mutex_inner);
47            false
48        } else {
49            // 锁空闲:直接占有。
50            mutex_inner.locked = true;
51            true
52        }
53    }
54    // 释放锁,释放之后会唤醒一个被阻塞的进程,要求重新进入调度队列
55    fn unlock(&self) -> Option<ThreadId> {
56        let mut mutex_inner = self.inner.exclusive_access();
57        assert!(mutex_inner.locked);
58        if let Some(waking_task) = mutex_inner.wait_queue.pop_front() {
59            // 注意:这里不清 locked,语义是“把锁转交给被唤醒线程”。
60            Some(waking_task)
61        } else {
62            mutex_inner.locked = false;
63            None
64        }
65    }
66}