8000 rp2: Fix build failure if threads are disabled. · sparkfun/micropython@71df9d0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 71df9d0

Browse files
committed
rp2: Fix build failure if threads are disabled.
Regression in 3af006e meant that pendsv.c no longer compiled if threads were disabled in the build config. Add an implementation based on the earlier one (simple counter) for the non-threads case. It seems like with the current usage patterns there's no need for the counter to be incremented/decremented atomically on a single core config. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent 8987b39 commit 71df9d0

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

ports/rp2/pendsv.c

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,14 @@
4343

4444
static pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS];
4545

46+
static inline void pendsv_resume_run_dispatch(void);
47+
4648
void PendSV_Handler(void);
4749

48-
// Using the nowait variant here as softtimer updates PendSV from the loop of mp_wfe_or_timeout(),
49-
// where we don't want the CPU event bit to be set.
50+
#if MICROPY_PY_THREAD
51+
52+
// Important to use a 'nowait' mutex here as softtimer updates PendSV from the
53+
// loop of mp_wfe_or_timeout(), where we don't want the CPU event bit to be set.
5054
sta 8000 tic mp_thread_recursive_mutex_t pendsv_mutex;
5155

5256
void pendsv_init(void) {
@@ -62,7 +66,40 @@ void pendsv_suspend(void) {
6266

6367
void pendsv_resume(void) {
6468
mp_thread_recursive_mutex_unlock(&pendsv_mutex);
69+
pendsv_resume_run_dispatch();
70+
}
71+
72+
static inline int pendsv_suspend_count(void) {
73+
return pendsv_mutex.mutex.enter_count;
74+
}
75+
76+
#else
77+
78+
// Without threads we don't include any pico-sdk mutex in the build,
79+
// but also we don't need to worry about cross-thread contention (or
80+
// races with interrupts that update this counter).
81+
static int pendsv_lock;
82+
83+
void pendsv_init(void) {
84+
}
85+
86+
void pendsv_suspend(void) {
87+
pendsv_lock++;
88+
}
89+
90+
void pendsv_resume(void) {
91+
assert(pendsv_lock > 0);
92+
pendsv_lock--;
93+
pendsv_resume_run_dispatch();
94+
}
6595

96+
static inline int pendsv_suspend_count(void) {
97+
return pendsv_lock;
98+
}
99+
100+
#endif
101+
102+
static inline void pendsv_resume_run_dispatch(void) {
66103
// Run pendsv if needed. Find an entry with a dispatch and call pendsv dispatch
67104
// with it. If pendsv runs it will service all slots.
68105
int count = PENDSV_DISPATCH_NUM_SLOTS;
@@ -76,7 +113,7 @@ void pendsv_resume(void) {
76113

77114
void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) {
78115
pendsv_dispatch_table[slot] = f;
79-
if (pendsv_mutex.mutex.enter_count == 0) {
116+
if (pendsv_suspend_count() == 0) {
80117
#if PICO_ARM
81118
// There is a race here where other core calls pendsv_suspend() before
82119
// ISR can execute, but dispatch will happen later when other core
@@ -97,13 +134,17 @@ void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) {
97134
// PendSV interrupt handler to perform background processing.
98135
void PendSV_Handler(void) {
99136

137+
#if MICROPY_PY_THREAD
100138
if (!mp_thread_recursive_mutex_lock(&pendsv_mutex, 0)) {
101139
// Failure here means core 1 holds pendsv_mutex. ISR will
102140
// run again after core 1 calls pendsv_resume().
103141
return;
104142
}
105143
// Core 0 should not already have locked pendsv_mutex
106144
assert(pendsv_mutex.mutex.enter_count == 1);
145+
#else
146+
assert(pendsv_suspend_count() == 0);
147+
#endif
107148

108149
#if MICROPY_PY_NETWORK_CYW43
109150
CYW43_STAT_INC(PENDSV_RUN_COUNT);
@@ -117,5 +158,7 @@ void PendSV_Handler(void) {
117158
}
118159
}
119160

161+
#if MICROPY_PY_THREAD
120162
mp_thread_recursive_mutex_unlock(&pendsv_mutex);
163+
#endif
121164
}

0 commit comments

Comments
 (0)
0