@@ -75,6 +75,8 @@ STATIC mp_thread_mutex_t thread_mutex;
75
75
STATIC thread_t thread_entry0 ;
76
76
STATIC thread_t * thread ; // root pointer, handled by mp_thread_gc_others
77
77
78
+ STATIC bool during_soft_reset = false;
79
+
78
80
void mp_thread_preinit (void * stack , uint32_t stack_len ) {
79
81
mp_thread_set_state (& mp_state_ctx .thread );
80
82
// create first entry in linked list of all threads
@@ -219,7 +221,19 @@ void mp_thread_finish(void) {
219
221
220
222
void vPortCleanUpTCB (void * tcb ) {
221
223
thread_t * prev = NULL ;
222
- mp_thread_mutex_lock (& thread_mutex , 1 );
224
+
225
+ /* If we are performing soft-reset the mutex has been already taken by mp_thread_deinit,
226
+ * do not try to take it here again as it causes deadlock.
227
+ * As the mutex is already taken, performing actions on the "thread" list is safe. */
228
+ if (during_soft_reset != true)
229
+ {
230
+ if (thread_mutex .handle == NULL )
231
+ {
232
+ mp_thread_mutex_init (& thread_mutex );
233
+ }
234
+ mp_thread_mutex_lock (& thread_mutex , 1 );
235
+ }
236
+
223
237
for (thread_t * th = thread ; th != NULL ; prev = th , th = th -> next ) {
224
238
// unlink the node from the list
225
239
if (th -> tcb == tcb ) {
@@ -229,7 +243,7 @@ void vPortCleanUpTCB (void *tcb) {
229
243
// move the start pointer
230
244
thread = th -> next ;
231
245
}
232
- // explicitely release all its memory
246
+ // explicitly release all its memory
233
247
if (esp_get_revision () > 0 ) {
234
248
free (th -> tcb );
235
249
free (th -> stack );
@@ -242,7 +256,10 @@ void vPortCleanUpTCB (void *tcb) {
242
256
break ;
243
257
}
244
258
}
245
- mp_thread_mutex_unlock (& thread_mutex );
259
+
260
+ if (during_soft_reset != true) {
261
+ mp_thread_mutex_unlock (& thread_mutex );
262
+ }
246
263
}
247
264
248
265
mp_obj_thread_lock_t * mp_thread_new_thread_lock (void ) {
@@ -270,13 +287,17 @@ void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
270
287
271
288
void mp_thread_deinit (void ) {
272
289
mp_thread_mutex_lock (& thread_mutex , 1 );
290
+ during_soft_reset = true;
291
+
273
292
for (thread_t * th = thread ; th != NULL ; th = th -> next ) {
274
293
// don't delete the current task
275
294
if (th ->id == xTaskGetCurrentTaskHandle ()) {
276
295
continue ;
277
296
}
278
297
vTaskDelete (th -> id );
279
298
}
299
+
300
+ during_soft_reset = false;
280
301
mp_thread_mutex_unlock (& thread_mutex );
281
302
// allow FreeRTOS to clean-up the threads
282
303
vTaskDelay (2 );
0 commit comments