8000 rp2/mpthreadport: Fix atomic section. · micropython/micropython@d062a6f · GitHub
[go: up one dir, main page]

Skip to content

Commit d062a6f

Browse files
committed
rp2/mpthreadport: Fix atomic section.
Two fixes: - Use a recursive mutex to prevent deadlocks on the same thread, if an IRQ races against the thread level when acquiring the lock (mutex may be taken but IRQs not yet disabled). - Unlock the mutex if it was locked, not if core1_entry is still non-null, to fix the case where the second core finishes while the first core is in the middle of an atomic operation. Signed-off-by: Damien George <damien@micropython.org>
1 parent ea24feb commit d062a6f

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines 10000 changed

ports/rp2/mpthreadport.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ STATIC uint32_t *core1_stack = NULL;
4545
STATIC size_t core1_stack_num_words = 0;
4646

4747
// Thread mutex.
48-
STATIC mp_thread_mutex_t atomic_mutex;
48+
STATIC recursive_mutex_t atomic_mutex;
49+
STATIC unsigned int atomic_taken;
4950

5051
uint32_t mp_thread_begin_atomic_section(void) {
5152
if (core1_entry) {
5253
// When both cores are executing, we also need to provide
5354
// full mutual exclusion.
54-
mp_thread_mutex_lock(&atomic_mutex, 1);
55+
recursive_mutex_enter_blocking(&atomic_mutex);
56+
++atomic_taken;
5557
}
5658

5759
return save_and_disable_interrupts();
@@ -60,16 +62,17 @@ uint32_t mp_thread_begin_atomic_section(void) {
6062
void mp_thread_end_atomic_section(uint32_t state) {
6163
restore_interrupts(state);
6264

63-
if (core1_entry) {
64-
mp_thread_mutex_unlock(&atomic_mutex);
65+
if (atomic_taken) {
66+
--atomic_taken;
67+
recursive_mutex_exit(&atomic_mutex);
6568
}
6669
}
6770

6871
// Initialise threading support.
6972
void mp_thread_init(void) {
7073
assert(get_core_num() == 0);
7174

72-
mp_thread_mutex_init(&atomic_mutex);
75+
recursive_mutex_init(&atomic_mutex);
7376

7477
// Allow MICROPY_BEGIN_ATOMIC_SECTION to be invoked from core1.
7578
multicore_lockout_victim_init();

0 commit comments

Comments
 (0)
0