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

3.6 KiB
Raw Permalink Blame History

与“等待”相关的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即可。

let mut wq = WaitQueue::INIT;

1.1.2 挂起进程

您可以这样挂起当前进程:

wq.sleep();

当前进程会被挂起,直到有另一个进程调用了wq.wakeup()

1.1.3 唤醒进程

您可以这样唤醒一个进程:

// 唤醒等待队列头部的进程如果它的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() 返回等待队列中的进程数量