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 */