diff --git a/ports/unix/btstack_usb.c b/ports/unix/btstack_usb.c index 76f32d6d27..ab6a49f39a 100644 --- a/ports/unix/btstack_usb.c +++ b/ports/unix/btstack_usb.c @@ -156,7 +156,10 @@ STATIC void *btstack_thread(void *arg) { // Or, if a timeout results in it being set to TIMEOUT. while (mp_bluetooth_btstack_state == MP_BLUETOOTH_BTSTACK_STATE_STARTING || mp_bluetooth_btstack_state == MP_BLUETOOTH_BTSTACK_STATE_ACTIVE) { + // Pretend like we're running in IRQ context (i.e. other things can't be running at the same time). + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); btstack_run_loop_embedded_execute_once(); + MICROPY_END_ATOMIC_SECTION(atomic_state); // The USB transport schedules events to the run loop at 1ms intervals, // and the implementation currently polls rather than selects. diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c index 711cf2a6bb..de0f5923ba 100644 --- a/ports/unix/mpthreadport.c +++ b/ports/unix/mpthreadport.c @@ -65,7 +65,7 @@ STATIC pthread_key_t tls_key; // The mutex is used for any code in this port that needs to be thread safe. // Specifically for thread management, access to the linked list is one example. // But also, e.g. scheduler state. -STATIC pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; +STATIC pthread_mutex_t thread_mutex; STATIC thread_t *thread; // this is used to synchronise the signal handler of the thread @@ -111,6 +111,13 @@ void mp_thread_init(void) { pthread_key_create(&tls_key, NULL); pthread_setspecific(tls_key, &mp_state_ctx.thread); + // Needs to be a recursive mutex to emulate the behavior of + // BEGIN_ATOMIC_SECTION on bare metal. + pthread_mutexattr_t thread_mutex_attr; + pthread_mutexattr_init(&thread_mutex_attr); + pthread_mutexattr_settype(&thread_mutex_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&thread_mutex, &thread_mutex_attr); + // create first entry in linked list of all threads thread = malloc(sizeof(thread_t)); thread->id = pthread_self();