我在裸机环境中操作,因此任何回答,仅使用您已有的内容都不适用,因为我没有任何内容。我正在编写系统驱动程序,但是我需要递归互斥体,但是我不知道如何实现它们。我目前只有一个自旋锁的计数信号量。是否可以根据信号量创建递归互斥体,还是必须创建另一个同步原语?不需要代码,我只想知道这些步骤。
答案 0 :(得分:1)
如果您对数据争用下发生的事情有一些较弱的好特性,那么它就轻而易举,本质上是:
/* data structure */
struct my_mutex {
sem_t sem;
volatile tid_t owner;
unsigned count;
} m;
/* lock operation */
if (m->owner == self) { // formally a race
m->cnt++;
} else {
sem_wait(&m->sem);
m->owner = self; // where self is tid of calling thread
}
/* unlock operation */
if (m->count > 0) {
m->count--;
} else {
m->owner = 0;
sem_post(&m->sem);
}
请注意,在没有排序的情况下,假设竞速读取从某些可能的排序中读取了一些价值,那么您可能无法在自己不将自己视为所有者的情况下,也可以在没有权限时将自己视为所有者的情况。但是,如果您将它们视为形式上未定义的,则无效。
如果无法做到这一点,通常需要一个普通的互斥锁+ condvar来模拟递归互斥锁,因此首先要弄清楚如何从一个信号量中创建一个condvar。
如果您的编译器具有_Atomic
并支持线程ID大小合适的原子(上面的抽象tid_t
类型;在裸机上您将定义这种类型),则可以使{ {1}}成员tid_t owner
并替换测试:
_Atomic
具有:
if (m->owner == self)
和if (atomic_load_explicit(&m->owner, memory_order_relaxed) == self)
限定符(基本上没有必要,但是向编译器发出信号,它不应拆分或合并负载,这有助于我在没有原子的情况下实现的“弱好特性” )可以删除。