支持 PI 的 RT 互斥子系统

具有优先级继承的 RT 互斥锁用于支持 PI-futexes,它能启用 pthread_mutex_t 优先级继承属性 (PTHREAD_PRIO_INHERIT)。[关于 PI-futexes 的更多细节,请参见轻量级 PI-futex。]

这项技术在 -rt 树中被开发,并为了 pthread_mutex 支持而进行了简化。

基本原则:

RT 互斥锁通过优先级继承协议扩展了简单互斥锁的语义。

一个低优先级的 rt-mutex 持有者会继承一个更高优先级等待者的优先级,直到 rt-mutex 被释放。如果临时提升的持有者本身阻塞在一个 rt-mutex 上,它会将优先级提升传播到它被阻塞的另一个 rt_mutex 的持有者。一旦 rt_mutex 被解锁,优先级提升会立即被移除。

这种方法允许我们缩短高优先级任务在保护共享资源的互斥锁上的阻塞时间。优先级继承不是为设计不良的应用程序准备的灵丹妙药,但它允许设计良好的应用程序在优先级高的线程的关键部分使用用户空间锁,而不会失去确定性。

等待者在 rtmutex 等待者树中的入队是按优先级顺序完成的。对于相同优先级,选择 FIFO 顺序。对于每个 rtmutex,只有最高优先级的等待者会被排队到持有者的优先级等待者树中。这个树也按优先级顺序排列。每当任务的最高优先级等待者发生变化时(例如,它超时或收到信号),持有者任务的优先级会被调整。优先级排队由“pi_waiters”处理。

RT 互斥锁针对快速路径操作进行了优化,并且在锁定未竞争的互斥锁或解锁没有等待者的互斥锁时没有内部锁定开销。优化的快速路径操作需要 cmpxchg 支持。[如果没有这个支持,那么将使用 rt-mutex 内部自旋锁]

rt-mutex 的状态通过 rt-mutex 结构的 owner 字段进行跟踪

lock->owner 保存持有者的 task_struct 指针。位 0 用于跟踪“锁有等待者”状态

owner

bit0

注释

NULL

0

锁是空闲的(可以快速获取)

NULL

1

锁是空闲的并且有等待者,并且最高优先级的等待者将要获取锁 [1]

taskpointer

0

锁被持有(可以快速释放)

taskpointer

1

锁被持有并且有等待者 [2]

只有当 lock->owner 的位 0 为 0 时,基于快速原子比较交换的获取和释放才有可能。

顺便说一下,实际上仍然存在一个“待定所有者”,只是不再这样称呼它了。 待定所有者恰好是没有所有者的锁的 top_waiter,并且已被唤醒以获取锁。