Skip to content

Instantly share code, notes, and snippets.

@tuankiet65
Created March 21, 2022 22:32
Show Gist options
  • Save tuankiet65/0a3d43fdf5dc3f77ae1581fd31270c1c to your computer and use it in GitHub Desktop.
Save tuankiet65/0a3d43fdf5dc3f77ae1581fd31270c1c to your computer and use it in GitHub Desktop.
Untested mutex implementation on bare-metal Cortex M4 (and maybe other Cortexes with LDREX/STREX)
#include "mutex.h"
/**
* Simple mutex implemented using LDREX/STREX, as described in
* https://developer.arm.com/documentation/dht0008/a/arm-synchronization-primitives/practical-uses/implementing-a-mutex.
*/
#include "stm32l476xx.h"
static const mutex_t MUTEX_UNLOCKED = 0;
static const mutex_t MUTEX_LOCKED = 1;
bool mutex_try_lock(volatile mutex_t *mutex) {
if (__LDREXB(mutex) == MUTEX_LOCKED)
return false;
/* Try to change mutex value to locked */
int strex_status = __STREXB(MUTEX_LOCKED, mutex);
__DMB();
/* strex_status == 0 when the store is successful, 1 otherwise */
return !strex_status;
}
void mutex_unlock(volatile mutex_t *mutex) {
__DMB();
*mutex = MUTEX_UNLOCKED;
}
#ifndef MUTEX_H
#define MUTEX_H
#include <stdbool.h>
#include <stdint.h>
typedef uint8_t mutex_t;
/**
* Attempt to acquire (or lock) a mutex.
* @param mutex the mutex to acquire.
* @return true if the mutex is successfully acquired, false otherwise
* (for example, if the mutex is already acquired)
*/
bool mutex_try_lock(volatile mutex_t *mutex);
/**
* Unlock a mutex. This will always unlock a mutex, even if the mutex is not locked.
* @param mutex the mutex to unlock.
*/
void mutex_unlock(volatile mutex_t *mutex);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment