diff options
-rw-r--r-- | core/nds32/task.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/core/nds32/task.c b/core/nds32/task.c index 9c3d6357ac..209395e86a 100644 --- a/core/nds32/task.c +++ b/core/nds32/task.c @@ -631,9 +631,18 @@ void __ram_code mutex_unlock(struct mutex *mtx) uint32_t waiters; task_ *tsk = current_task; - waiters = mtx->waiters; - /* give back the lock */ - mtx->lock = 0; + /* + * we need to read to waiters after giving the lock back + * otherwise we might miss a waiter between the two calls. + * + * prevent compiler reordering + */ + asm volatile( + /* give back the lock */ + "movi %0, #0\n\t" + "lwi %1, [%2]\n\t" + : "=&r"(mtx->lock), "=&r"(waiters) + : "r"(&mtx->waiters)); while (waiters) { task_id_t id = __fls(waiters); |