Skip to content

Commit cee4537

Browse files
committed
chore: switch to cgo inline asm
1 parent ab8bf89 commit cee4537

File tree

1 file changed

+41
-8
lines changed

1 file changed

+41
-8
lines changed

src/runtime/runtime_rp2350.go

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,40 @@
22

33
package 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+
536
import (
637
"device/rp"
7-
"sync/atomic"
38+
"unsafe"
839
)
940

1041
const (
@@ -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+
1953
type spinLock struct {
20-
atomic.Uint32
21-
id uint8
54+
state uint8
55+
id uint8
56+
_ [2]uint8
2257
}
2358

2459
func (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

3164
func (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

Comments
 (0)