runtime: make sure mutex waiters are woken up
@@ -20,13 +20,6 @@ void __mutex_lock(mutex_t *m)
thread_t *myth = thread_self();
spin_lock(&m->waiter_lock);
- /* was the mutex released before we acquired the waiter lock? */
- if (!atomic_read(&m->state)) {
- if (!atomic_fetch_and_add(&m->state, 1)) {
- spin_unlock(&m->waiter_lock);
- return;
- }
- }
list_add_tail(&m->waiters, &myth->link);
thread_park_and_unlock(&m->waiter_lock);
}
@@ -36,14 +29,15 @@ void __mutex_unlock(mutex_t *m)
{
thread_t *waketh;
+ while (true) {
spin_lock(&m->waiter_lock);
waketh = list_pop(&m->waiters, thread_t, link);
- if (!waketh) {
- atomic_write(&m->state, 0);
spin_unlock(&m->waiter_lock);
- return;
+ if (waketh)
+ break;
+ thread_yield();
}
- spin_unlock(&m->waiter_lock);
+
thread_ready(waketh);
}
