Используя счетный семафор, как мне создать рекурсивный мьютекс - PullRequest
0 голосов
/ 17 декабря 2018

Я работаю в голой металлической среде, поэтому любые ответы, в которых говорится только о том, что вы используете, неприменимы, поскольку у меня ничего нет.Я пишу системный драйвер, но мне нужны рекурсивные мьютексы, но я не могу понять, как их реализовать.В настоящее время у меня есть только счетный семафор, который работает как спин-блокировка.Можно ли создать рекурсивный мьютекс из семафора или мне нужно создать еще один примитив синхронизации, и если да, то как?Код не требуется, я просто хотел бы знать шаги, пожалуйста.

1 Ответ

0 голосов
/ 17 декабря 2018

Если у вас есть довольно слабые приятные свойства в отношении того, что происходит в гонках данных, это легко и просто, по сути:

/* 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);
}

Обратите внимание, что не существует порядка, при котором вы могли бы не видеть себя каквладелец, когда вы есть, и не считайте себя владельцем, если вы не являетесь, предполагая, что гоночные чтения читают некоторую ценность из некоторого возможного заказа.Но если вы рассматриваете их как формально неопределенные, это недопустимо.

Если вы не можете этого сделать, вам обычно нужен обычный mutex + condvar для эмуляции рекурсивного мьютекса, поэтому сначала выясните, как создать condvarиз семафора.

Если ваш компилятор имеет _Atomic и поддерживает атомарность правильного размера для идентификаторов потоков (абстрактный тип tid_t выше; для голого металла это тип, который вы бы определили), вы можетесделайте tid_t owner member _Atomic и замените тест:

if (m->owner == self)

на:

if (atomic_load_explicit(&m->owner, memory_order_relaxed) == self)

и квалификатор volatile (по большей части ненужный, но в качестве сигнала длякомпилятор, который не должен разделять или объединять нагрузки, что помогает с «слабыми хорошими свойствами», к которым я стремился в отсутствие атомарности), может быть удален.

...