47 lines
1.6 KiB
ArmAsm
47 lines
1.6 KiB
ArmAsm
|
|
.syntax unified
|
|
|
|
/* Lock function.
|
|
* On success, return 0.
|
|
* On failure, return -1 (Locked, try again later).
|
|
*/
|
|
|
|
.global _mutex_lock
|
|
_mutex_lock:
|
|
LDREX r1, [r0]
|
|
CMP r1, #0 // Test if mutex holds the value 0
|
|
BEQ _mutex_lock_fail // If it does, return -1
|
|
SUBS r1, #1 // If not, decrement temporary copy
|
|
STREX r2, r1, [r0] // Attempt Store-Exclusive
|
|
CMP r2, #0 // Check if Store-Exclusive succeeded
|
|
BNE _mutex_lock // If Store-Exclusive failed, retry from start
|
|
DMB // Required before accessing protected resource
|
|
MOVS r0, #0 // Successfully locked.
|
|
BX lr
|
|
_mutex_lock_fail:
|
|
DMB
|
|
MOV r0, #-1 // Already locked!
|
|
BX lr
|
|
|
|
/* Unlock mutex.
|
|
* On success, return 0.
|
|
* On failure, return -1 (Already unlocked!).
|
|
*/
|
|
|
|
.global _mutex_unlock
|
|
_mutex_unlock:
|
|
LDREX r1, [r0]
|
|
CMP r1, #0 // Test if mutex holds the value 0
|
|
BNE _mutex_unlock_fail // If it does not, it's already unlocked!
|
|
ADDS r1, #1 // Increment temporary copy
|
|
STREX r2, r1, [r0] // Attempt Store-Exclusive
|
|
CMP r2, #0 // Check if Store-Exclusive succeeded
|
|
BNE _mutex_unlock // Store failed - retry immediately
|
|
DMB // Required before releasing protected resource
|
|
MOVS r0, #0 // Successfully unlocked.
|
|
BX lr
|
|
_mutex_unlock_fail:
|
|
DMB
|
|
MOV r0, #-1 // Already unlocked!
|
|
BX lr
|
|
|