Skip to content

Commit 7fb00d8

Browse files
committed
Revert "extmod/zephyr_kernel: Fix GIL deadlock with k_sem instead of k_mutex."
This reverts commit 57e6e61.
1 parent 28d3db1 commit 7fb00d8

File tree

2 files changed

+13
-20
lines changed

2 files changed

+13
-20
lines changed

extmod/zephyr_kernel/kernel/mpthread_zephyr.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -384,43 +384,38 @@ void mp_thread_finish(void) {
384384
mp_thread_mutex_unlock(&thread_mutex);
385385
}
386386

387-
// Initialize mutex - use Zephyr's k_sem (binary semaphore)
388-
// Need a binary semaphore so a lock can be acquired on one Python thread
389-
// and then released on another (required for GIL).
387+
// Initialize mutex - use Zephyr's k_mutex (recursive by default)
390388
void mp_thread_mutex_init(mp_thread_mutex_t *mutex) {
391-
k_sem_init(&mutex->handle, 0, 1);
392-
k_sem_give(&mutex->handle);
389+
k_mutex_init(&mutex->handle);
393390
}
394391

395392
// Lock mutex
396393
int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) {
397-
int ret = k_sem_take(&mutex->handle, wait ? K_FOREVER : K_NO_WAIT);
394+
int ret = k_mutex_lock(&mutex->handle, wait ? K_FOREVER : K_NO_WAIT);
398395
return ret == 0; // Return 1 on success, 0 on failure
399396
}
400397

401398
// Unlock mutex
402399
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
403-
k_sem_give(&mutex->handle);
404-
k_yield();
400+
k_mutex_unlock(&mutex->handle);
401+
// Note: Do NOT call k_yield() here - it can cause crashes during thread
402+
// creation/destruction and the Zephyr scheduler will handle preemption
405403
}
406404

407405
// Recursive mutex functions (for GC and memory allocation)
408-
// Note: k_sem is not inherently recursive, but MicroPython's usage pattern
409-
// typically doesn't require true recursion for these mutexes.
406+
// Zephyr's k_mutex is recursive by default, so these are the same as regular mutex
410407

411408
void mp_thread_recursive_mutex_init(mp_thread_recursive_mutex_t *mutex) {
412-
k_sem_init(&mutex->handle, 0, 1);
413-
k_sem_give(&mutex->handle);
409+
k_mutex_init(&mutex->handle);
414410
}
415411

416412
int mp_thread_recursive_mutex_lock(mp_thread_recursive_mutex_t *mutex, int wait) {
417-
int ret = k_sem_take(&mutex->handle, wait ? K_FOREVER : K_NO_WAIT);
413+
int ret = k_mutex_lock(&mutex->handle, wait ? K_FOREVER : K_NO_WAIT);
418414
return ret == 0; // Return 1 on success, 0 on failure
419415
}
420416

421417
void mp_thread_recursive_mutex_unlock(mp_thread_recursive_mutex_t *mutex) {
422-
k_sem_give(&mutex->handle);
423-
k_yield();
418+
k_mutex_unlock(&mutex->handle);
424419
}
425420

426421
// Helper: Thread iteration callback for GC

ports/stm32/mpthreadport_zephyr.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@
3131

3232
#include <zephyr/kernel.h>
3333

34-
// Mutex types using Zephyr k_sem (binary semaphore)
35-
// Need a binary semaphore so a lock can be acquired on one Python thread
36-
// and then released on another (required for GIL).
34+
// Mutex types using Zephyr k_mutex
3735
typedef struct _mp_thread_mutex_t {
38-
struct k_sem handle;
36+
struct k_mutex handle;
3937
} mp_thread_mutex_t;
4038

4139
typedef struct _mp_thread_recursive_mutex_t {
42-
struct k_sem handle;
40+
struct k_mutex handle;
4341
} mp_thread_recursive_mutex_t;
4442

4543
// Threading functions (implemented in extmod/zephyr_kernel/mpthread_zephyr.c)

0 commit comments

Comments
 (0)