2
2
3
3
package runtime
4
4
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
+
5
36
import (
6
37
"device/rp"
7
- "sync/atomic "
38
+ "unsafe "
8
39
)
9
40
10
41
const (
@@ -16,24 +47,26 @@ const (
16
47
sioIrqFifoProc1 = rp .IRQ_SIO_IRQ_FIFO
17
48
)
18
49
50
+ // Software spinlocks don't persist across soft resets so this is a no-op.
51
+ func resetSpinLocks () {}
52
+
19
53
type spinLock struct {
20
- atomic.Uint32
21
- id uint8
54
+ state uint8
55
+ id uint8
56
+ _ [2 ]uint8
22
57
}
23
58
24
59
func (l * spinLock ) Lock () {
25
60
// 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 ))
29
62
}
30
63
31
64
func (l * spinLock ) Unlock () {
32
65
// Safety check: the spinlock should have been locked.
33
- if schedulerAsserts && l .Uint32 . Load () != 1 {
66
+ if schedulerAsserts && l .state != 1 {
34
67
runtimePanic ("unlock of unlocked spinlock" )
35
68
}
36
69
37
70
// 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 ) )
39
72
}
0 commit comments