DragonOS/docs/kernel/sched/rust_waiting.md
login 151251b50b
Patch add rust waitqueue (#162)
* new: rust版本的waitqueue

* new:等待队列的文档
2023-01-31 19:27:02 +08:00

82 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 与“等待”相关的apirust语言
  如果几个进程需要等待某个事件发生,才能被运行,那么就需要一种“等待”的机制,以实现进程同步。
## 1. WaitQueue等待队列
   WaitQueue是一种进程同步机制中文名为“等待队列”。它可以将当前进程挂起并在时机成熟时由另一个进程唤醒他们。
  当您需要等待一个事件完成时,使用 WaitQueue机制能减少进程同步的开销。相比于滥用自旋锁以及信号量或者是循环使用usleep(1000)这样的函数来完成同步, WaitQueue是一个高效的解决方案。
### 1.1 WaitQueue的使用
   WaitQueue的使用非常简单只需要三步
1. 初始化一个WaitQueue对象。
2. 调用这个WaitQueue的挂起相关的API将当前进程挂起。
3. 当事件发生时由另一个进程调用这个WaitQueue的唤醒相关的API唤醒一个进程。
  下面是一个简单的例子:
### 1.1.1 初始化一个WaitQueue对象
   WaitQueue对象的初始化非常简单只需要调用WaitQueue::INIT即可。
```rust
let mut wq = WaitQueue::INIT;
```
### 1.1.2 挂起进程
   您可以这样挂起当前进程:
```rust
wq.sleep();
```
   当前进程会被挂起,直到有另一个进程调用了`wq.wakeup()`
### 1.1.3 唤醒进程
   您可以这样唤醒一个进程:
```rust
// 唤醒等待队列头部的进程如果它的state & PROC_INTERRUPTIBLE 不为0
wq.wakeup(PROC_INTERRUPTIBLE);
// 唤醒等待队列头部的进程如果它的state & PROC_UNINTERRUPTIBLE 不为0
wq.wakeup(PROC_UNINTERRUPTIBLE);
// 唤醒等待队列头部的进程无论它的state是什么
wq.wakeup((-1) as u64);
```
### 1.2 API
### 1.2.1 挂起进程
  您可以使用以下函数,将当前进程挂起,并插入到指定的等待队列。这些函数大体功能相同,只是在一些细节上有所不同。
| 函数名 | 解释 |
| --------------------------------------- | ------------------------------------------------------------- |
| sleep() | 将当前进程挂起并设置进程状态为PROC_INTERRUPTIBLE |
| sleep_uninterruptible() | 将当前进程挂起并设置进程状态为PROC_UNINTERRUPTIBLE |
| sleep_unlock_spinlock() | 将当前进程挂起并设置进程状态为PROC_INTERRUPTIBLE。待当前进程被插入等待队列后解锁给定的自旋锁 |
| sleep_unlock_mutex() | 将当前进程挂起并设置进程状态为PROC_INTERRUPTIBLE。待当前进程被插入等待队列后解锁给定的Mutex |
| sleep_uninterruptible_unlock_spinlock() | 将当前进程挂起并设置进程状态为PROC_UNINTERRUPTIBLE。待当前进程被插入等待队列后解锁给定的自旋锁 |
| sleep_uninterruptible_unlock_mutex() | 将当前进程挂起并设置进程状态为PROC_UNINTERRUPTIBLE。待当前进程被插入等待队列后解锁给定的Mutex |
### 1.2.2 唤醒进程
  您可以使用`wakeup(state)`函数唤醒等待队列中的第一个进程。如果这个进程的state与给定的state进行and操作之后结果不为0,则唤醒它。
  返回值如果有进程被唤醒则返回true否则返回false。
### 1.2.3 其它API
| 函数名 | 解释 |
| ----- | ------------ |
| len() | 返回等待队列中的进程数量 |