mutex.S 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. .syntax unified
  2. /* Lock function.
  3. * On success, return 0.
  4. * On failure, return -1 (Locked, try again later).
  5. */
  6. .global _mutex_lock
  7. _mutex_lock:
  8. LDREX r1, [r0]
  9. CMP r1, #0 // Test if mutex holds the value 0
  10. BEQ _mutex_lock_fail // If it does, return -1
  11. SUBS r1, #1 // If not, decrement temporary copy
  12. STREX r2, r1, [r0] // Attempt Store-Exclusive
  13. CMP r2, #0 // Check if Store-Exclusive succeeded
  14. BNE _mutex_lock // If Store-Exclusive failed, retry from start
  15. DMB // Required before accessing protected resource
  16. MOVS r0, #0 // Successfully locked.
  17. BX lr
  18. _mutex_lock_fail:
  19. DMB
  20. MOV r0, #-1 // Already locked!
  21. BX lr
  22. /* Unlock mutex.
  23. * On success, return 0.
  24. * On failure, return -1 (Already unlocked!).
  25. */
  26. .global _mutex_unlock
  27. _mutex_unlock:
  28. LDREX r1, [r0]
  29. CMP r1, #0 // Test if mutex holds the value 0
  30. BNE _mutex_unlock_fail // If it does not, it's already unlocked!
  31. ADDS r1, #1 // Increment temporary copy
  32. STREX r2, r1, [r0] // Attempt Store-Exclusive
  33. CMP r2, #0 // Check if Store-Exclusive succeeded
  34. BNE _mutex_unlock // Store failed - retry immediately
  35. DMB // Required before releasing protected resource
  36. MOVS r0, #0 // Successfully unlocked.
  37. BX lr
  38. _mutex_unlock_fail:
  39. DMB
  40. MOV r0, #-1 // Already unlocked!
  41. BX lr