summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2016-10-19 14:24:56 +1100
committerDamien George <damien.p.george@gmail.com>2016-10-19 14:24:56 +1100
commit17ba6ef5fa7585d3e91dada3044e8e755cf99537 (patch)
treee1efc06edcae56f2f9c41151c3441b6e27571d4c
parent204222653edbc2d01b5aed38b1de71a767cb5748 (diff)
downloadmicropython-17ba6ef5fa7585d3e91dada3044e8e755cf99537.tar.gz
micropython-17ba6ef5fa7585d3e91dada3044e8e755cf99537.zip
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 #2406.
-rw-r--r--cc3200/mpthreadport.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/cc3200/mpthreadport.c b/cc3200/mpthreadport.c
index dd02180982..e77ac4ae53 100644
--- a/cc3200/mpthreadport.c
+++ b/cc3200/mpthreadport.c
@@ -31,8 +31,10 @@
#include "py/runtime.h"
#include "py/gc.h"
#include "py/mpthread.h"
+#include "py/mphal.h"
#include "mptask.h"
#include "task.h"
+#include "irq.h"
#if MICROPY_PY_THREAD
@@ -166,14 +168,23 @@ void mp_thread_mutex_init(mp_thread_mutex_t *mutex) {
mutex->handle = xSemaphoreCreateMutexStatic(&mutex->buffer);
}
+// To allow hard interrupts to work with threading we only take/give the semaphore
+// if we are not within an interrupt context and interrupts are enabled.
+
int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) {
- int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
- return ret == pdTRUE;
+ if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
+ int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
+ return ret == pdTRUE;
+ } else {
+ return 1;
+ }
}
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
- xSemaphoreGive(mutex->handle);
- // TODO check return value
+ if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
+ xSemaphoreGive(mutex->handle);
+ // TODO check return value
+ }
}
#endif // MICROPY_PY_THREAD