22
33package runtime
44
5+ // #include <stdint.h>
6+ //
7+ // static void spinlock_lock(void *lock) {
8+ // uint32_t _tmp0, _tmp1;
9+ // __asm volatile ( \
10+ // "1:\n" \
11+ // "ldaexb %1, [%2]\n" \
12+ // "movs %0, #1\n" /* fill dependency slot */ \
13+ // "cmp %1, #0\n" \
14+ // /* Immediately retry if lock is seen to be taken */ \
15+ // "bne 1b\n" \
16+ // /* Attempt to claim */ \
17+ // "strexb %1, %0, [%2]\n" \
18+ // "cmp %1, #0\n" \
19+ // /* Claim failed due to intervening write, so retry */ \
20+ // "bne 1b\n" \
21+ // : "=&r" (_tmp0), "=&r" (_tmp1) : "r" (lock) \
22+ // ); \
23+ // __asm volatile ("dmb" : : : "memory");
24+ // }
25+ //
26+ // static void spinlock_unlock(void *lock) {
27+ // /* Release-ordered store is available: use instead of separate fence */ \
28+ // uint32_t zero = 0; \
29+ // __asm volatile ( \
30+ // "stlb %0, [%1]\n" \
31+ // : : "r" (zero), "r" (lock) \
32+ // ); \
33+ // }
34+ import "C"
35+
536import (
637 "device/rp"
7- "sync/atomic "
38+ "unsafe "
839)
940
1041const (
@@ -16,24 +47,26 @@ const (
1647 sioIrqFifoProc1 = rp .IRQ_SIO_IRQ_FIFO
1748)
1849
50+ // Software spinlocks don't persist across soft resets so this is a no-op.
51+ func resetSpinLocks () {}
52+
1953type spinLock struct {
20- atomic.Uint32
21- id uint8
54+ state uint8
55+ id uint8
56+ _ [2 ]uint8
2257}
2358
2459func (l * spinLock ) Lock () {
2560 // Try to replace 0 with 1. Once we succeed, the lock has been acquired.
26- for ! l .Uint32 .CompareAndSwap (0 , 1 ) {
27- spinLoopWait ()
28- }
61+ C .spinlock_lock (unsafe .Pointer (& l .state ))
2962}
3063
3164func (l * spinLock ) Unlock () {
3265 // Safety check: the spinlock should have been locked.
33- if schedulerAsserts && l .Uint32 . Load () != 1 {
66+ if schedulerAsserts && l .state != 1 {
3467 runtimePanic ("unlock of unlocked spinlock" )
3568 }
3669
3770 // Unlock the lock. Simply write 0, because we already know it is locked.
38- l . Uint32 . Store ( 0 )
71+ C . spinlock_unlock ( unsafe . Pointer ( & l . state ) )
3972}
0 commit comments