diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/cortex-m/task.c | 14 | ||||
-rw-r--r-- | core/cortex-m0/task.c | 14 |
2 files changed, 18 insertions, 10 deletions
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index 112c32299d..f23b8142ff 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -539,11 +539,15 @@ void mutex_unlock(struct mutex *mtx) uint32_t waiters; task_ *tsk = current_task; - __asm__ __volatile__(" ldr %0, [%2]\n" - " str %3, [%1]\n" - : "=&r" (waiters) - : "r" (&mtx->lock), "r" (&mtx->waiters), "r" (0) - : "cc"); + /* + * Add a critical section to keep the unlock and the snapshotting of + * waiters atomic in case a task switching occurs between them. + */ + interrupt_disable(); + waiters = mtx->waiters; + mtx->lock = 0; + interrupt_enable(); + while (waiters) { task_id_t id = __fls(waiters); waiters &= ~(1 << id); diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c index 3bbee70cae..8796983127 100644 --- a/core/cortex-m0/task.c +++ b/core/cortex-m0/task.c @@ -530,11 +530,15 @@ void mutex_unlock(struct mutex *mtx) uint32_t waiters; task_ *tsk = current_task; - __asm__ __volatile__(" ldr %0, [%2]\n" - " str %3, [%1]\n" - : "=&r" (waiters) - : "r" (&mtx->lock), "r" (&mtx->waiters), "r" (0) - : "cc"); + /* + * Add a critical section to keep the unlock and the snapshotting of + * waiters atomic in case a task switching occurs between them. + */ + interrupt_disable(); + waiters = mtx->waiters; + mtx->lock = 0; + interrupt_enable(); + while (waiters) { task_id_t id = __fls(waiters); waiters &= ~(1 << id); |