Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3af006e

Browse files
projectgusdpgeorge
authored andcommitted
rp2: Support calling pendsv_suspend/resume from core 1.
Previously, this was subject to races incrementing/decrementingthe counter variable pendsv_lock.Technically, all that's needed here would be to make pendsv_lock an atomiccounter.This implementation fulfils a stronger guarantee: it also provides mutualexclusion for the core which calls pendsv_suspend(). This is because thecurrent use of pendsv_suspend/resume in MicroPython is to ensure exclusiveaccess to softtimer data structures, and this does require mutualexclusion.The conceptually cleaner implementation would split the mutual exclusionpart out into a softtimer-specific spinlock, but this increases thecomplexity and doesn't seem like it makes for a better implementation inthe long run.This work was funded through GitHub Sponsors.Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent83e82c5 commit3af006e

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

‎ports/rp2/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ int main(int argc, char **argv) {
7676
// This is a tickless port, interrupts should always trigger SEV.
7777
SCB->SCR |=SCB_SCR_SEVONPEND_Msk;
7878

79+
pendsv_init();
7980
soft_timer_init();
8081

8182
#ifMICROPY_HW_ENABLE_UART_REPL

‎ports/rp2/pendsv.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626

2727
#include<assert.h>
28+
#include"pico/mutex.h"
2829
#include"py/mpconfig.h"
2930
#include"pendsv.h"
3031
#include"RP2040.h"
@@ -34,15 +35,21 @@
3435
#endif
3536

3637
staticpendsv_dispatch_tpendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS];
37-
staticintpendsv_lock;
38+
staticrecursive_mutex_tpendsv_mutex;
39+
40+
voidpendsv_init(void) {
41+
recursive_mutex_init(&pendsv_mutex);
42+
}
3843

3944
voidpendsv_suspend(void) {
40-
pendsv_lock++;
45+
// Recursive Mutex here as either core may call pendsv_suspend() and expect
46+
// both mutual exclusion (other core can't enter pendsv_suspend() at the
47+
// same time), and that no PendSV handler will run.
48+
recursive_mutex_enter_blocking(&pendsv_mutex);
4149
}
4250

4351
voidpendsv_resume(void) {
44-
pendsv_lock--;
45-
assert(pendsv_lock >=0);
52+
recursive_mutex_exit(&pendsv_mutex);
4653
// Run pendsv if needed. Find an entry with a dispatch and call pendsv dispatch
4754
// with it. If pendsv runs it will service all slots.
4855
intcount=PENDSV_DISPATCH_NUM_SLOTS;
@@ -55,9 +62,11 @@ void pendsv_resume(void) {
5562
}
5663

5764
voidpendsv_schedule_dispatch(size_tslot,pendsv_dispatch_tf) {
58-
assert(pendsv_lock >=0);
5965
pendsv_dispatch_table[slot]=f;
60-
if (pendsv_lock==0) {
66+
if (pendsv_mutex.enter_count==0) {
67+
// There is a race here where other core calls pendsv_suspend() before
68+
// ISR can execute, but dispatch will happen later when other core
69+
// calls pendsv_resume().
6170
SCB->ICSR=SCB_ICSR_PENDSVSET_Msk;
6271
}else {
6372
#ifMICROPY_PY_NETWORK_CYW43
@@ -68,7 +77,14 @@ void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) {
6877

6978
// PendSV interrupt handler to perform background processing.
7079
voidPendSV_Handler(void) {
71-
assert(pendsv_lock==0);
80+
81+
if (!recursive_mutex_try_enter(&pendsv_mutex,NULL)) {
82+
// Failure here means core 1 holds pendsv_mutex. ISR will
83+
// run again after core 1 calls pendsv_resume().
84+
return;
85+
}
86+
// Core 0 should not already have locked pendsv_mutex
87+
assert(pensv_mutex.enter_count==1);
7288

7389
#ifMICROPY_PY_NETWORK_CYW43
7490
CYW43_STAT_INC(PENDSV_RUN_COUNT);
@@ -81,4 +97,6 @@ void PendSV_Handler(void) {
8197
f();
8298
}
8399
}
100+
101+
recursive_mutex_exit(&pendsv_mutex);
84102
}

‎ports/rp2/pendsv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum {
4747

4848
typedefvoid (*pendsv_dispatch_t)(void);
4949

50+
voidpendsv_init(void);
5051
voidpendsv_suspend(void);
5152
voidpendsv_resume(void);
5253
voidpendsv_schedule_dispatch(size_tslot,pendsv_dispatch_tf);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp