8000 cc3200: Fix thread mutex's so threading works with interrupts. · ladyada/circuitpython@17ba6ef · GitHub
[go: up one dir, main page]

Skip to content

Commit 17ba6ef

Browse files
committed
cc3200: Fix thread mutex's so threading works with interrupts.
Running Python code on a hard interrupt is incompatible with having a GIL, because most of the time the GIL will be held by the user thread when the interrupt arrives. Hard interrupts mean that we should process them right away and hence can't wait until the GIL is released. The problem with the current code is that a hard interrupt will try to exit/enter the GIL while it is still held by the user thread, hence leading to a deadlock. This patch works around such a problem by just making GIL exit/enter a no-op when in an interrupt context, or when interrupts are disabled. See issue adafruit#2406.
1 parent 2042226 commit 17ba6ef

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

cc3200/mpthreadport.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
#include "py/runtime.h"
3232
#include "py/gc.h"
3333
#include "py/mpthread.h"
34+
#include "py/mphal.h"
3435
#include "mptask.h"
3536
#include "task.h"
37+
#include "irq.h"
3638

3739
#if MICROPY_PY_THREAD
3840

@@ -166,14 +168,23 @@ void mp_thread_mutex_init(mp_thread_mutex_t *mutex) {
166168
mutex->handle = xSemaphoreCreateMutexStatic(&mutex->buffer);
167169
}
168170

171+
// To allow hard interrupts to work with threading we only take/give the semaphore
172+
// if we are not within an interrupt context and interrupts are enabled.
173+
169174
int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) {
170-
int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
171-
return ret == pdTRUE;
175+
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
176+
int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
177+
return ret == pdTRUE;
178+
} else {
179+
return 1;
180+
}
172181
}
173182

174183
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
175-
xSemaphoreGive(mutex->handle);
176-
// TODO check return value
184+
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
185+
xSemaphoreGive(mutex->handle);
186+
// TODO check return value
187+
}
177188
}
178189

179190
#endif // MICROPY_PY_THREAD

0 commit comments

Comments
 (0)
0