From a2fe6c49a8c3e86bd2bc30d9cac1d14b968bc3f5 Mon Sep 17 00:00:00 2001 From: Oliver Meier Date: Fri, 5 Dec 2014 16:47:52 +0100 Subject: [PATCH] [cm3/sync] Add mutex_trylock() Allows non-blocking use in user code. --- include/libopencm3/cm3/sync.h | 1 + lib/cm3/sync.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/libopencm3/cm3/sync.h b/include/libopencm3/cm3/sync.h index e80e3485..93c12bbd 100644 --- a/include/libopencm3/cm3/sync.h +++ b/include/libopencm3/cm3/sync.h @@ -47,6 +47,7 @@ typedef uint32_t mutex_t; #define MUTEX_LOCKED 1 void mutex_lock(mutex_t *m); +uint32_t mutex_trylock(mutex_t *m); void mutex_unlock(mutex_t *m); #endif diff --git a/lib/cm3/sync.c b/lib/cm3/sync.c index 906138ab..a9f7c99a 100644 --- a/lib/cm3/sync.c +++ b/lib/cm3/sync.c @@ -61,6 +61,25 @@ void mutex_lock(mutex_t *m) __dmb(); } +/* returns 1 if the lock was acquired */ +uint32_t mutex_trylock(mutex_t *m) +{ + uint32_t status = 0; + + /* If the mutex is unlocked. */ + if (__ldrex(m) == MUTEX_UNLOCKED) { + /* Try to lock it. */ + status = __strex(MUTEX_LOCKED, m); + } + + /* Execute the mysterious Data Memory Barrier instruction! */ + __dmb(); + + /* Did we get the lock? If not then try again + * by calling this function once more. */ + return status == 0; +} + void mutex_unlock(mutex_t *m) { /* Ensure accesses to protected resource are finished */