@@ -73,7 +73,6 @@ typedef struct _mp_thread_t {
7373 void * arg ; // Python args (GC root pointer)
7474 void * stack ; // Stack pointer
7575 size_t stack_len ; // Stack size in words
76- mp_state_thread_t * thread_state ;// Python thread state (GC root)
7776 struct _mp_thread_t * next ; // Next in linked list
7877} mp_thread_t ;
7978
@@ -103,7 +102,6 @@ bool mp_thread_init(void *stack) {
103102 thread_entry0 .arg = NULL ;
104103 thread_entry0 .stack = stack ;
105104 thread_entry0 .stack_len = 0 ; // Bootstrap thread uses C runtime stack, size unknown
106- thread_entry0 .thread_state = & mp_state_ctx .thread ; // Main thread uses global state
107105 thread_entry0 .next = NULL ;
108106
109107 k_thread_name_set (thread_entry0 .id , "mp_main" );
@@ -190,7 +188,6 @@ void mp_thread_gc_others(void) {
190188
191189 gc_collect_root ((void * * )& th , 1 );
192190 gc_collect_root (& th -> arg , 1 );
193- gc_collect_root ((void * * )& th -> thread_state , 1 ); // Scan thread state
194191
195192 if (th -> id == k_current_get ()) {
196193 continue ; // Don't scan current thread's stack (done separately)
@@ -239,59 +236,11 @@ void mp_thread_start(void) {
239236static void zephyr_entry (void * arg1 , void * arg2 , void * arg3 ) {
240237 (void )arg3 ;
241238
242- // Get the mp_thread_t structure for this thread (passed via arg3 actually stored in custom_data)
243- // Find our thread in the list
244- mp_thread_t * self = NULL ;
245- k_tid_t current_tid = k_current_get ();
246-
247- mp_thread_mutex_lock (& thread_mutex , 1 );
248- for (mp_thread_t * th = thread ; th != NULL ; th = th -> next ) {
249- if (th -> id == current_tid ) {
250- self = th ;
251- break ;
252- }
253- }
254- mp_thread_mutex_unlock (& thread_mutex );
255-
256- if (self == NULL || self -> thread_state == NULL ) {
257- // Fatal error - thread state not set up
258- k_thread_abort (current_tid );
259- for (;;) { ; }
260- }
261-
262- // Set up thread-local storage using pre-allocated state
263- mp_thread_set_state (self -> thread_state );
264-
265- // Initialize thread state fields
266- self -> thread_state -> gc_lock_depth = 0 ;
267- self -> thread_state -> nlr_top = NULL ;
268- self -> thread_state -> nlr_jump_callback_top = NULL ;
269- self -> thread_state -> mp_pending_exception = MP_OBJ_NULL ;
270-
271- // Inherit globals/locals from main thread
272- mp_locals_set (mp_state_ctx .thread .dict_locals );
273- mp_globals_set (mp_state_ctx .thread .dict_globals );
274-
275- // Get stack info from current thread
276- struct k_thread * current = k_current_get ();
277- void * stack_top = (void * )((uintptr_t )current -> stack_info .start + current -> stack_info .size );
278- size_t stack_limit = current -> stack_info .size - 1024 ; // Leave margin for Zephyr
279-
280- // Set up stack bounds for Python stack checking
281- mp_stack_set_top (stack_top );
282- mp_stack_set_limit (stack_limit );
283-
284- // Mark thread as started (updates status to READY)
285- mp_thread_start ();
286-
287- // Now safe to execute Python code
239+ // arg1 contains the python thread entry point
288240 if (arg1 ) {
289241 void * (* entry )(void * ) = arg1 ;
290242 entry (arg2 );
291243 }
292-
293- // Clean up when thread finishes
294- mp_thread_finish ();
295244 k_thread_abort (k_current_get ());
296245 for (;;) {
297246 ; // Never reached
@@ -310,36 +259,32 @@ mp_uint_t mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_s
310259 // Try to garbage collect old threads
311260 gc_collect ();
312261
313- // Allocate thread node and thread state (must be outside mutex lock for GC)
262+ // Allocate thread node (must be outside mutex lock for GC)
314263 mp_thread_t * th = m_new_obj (mp_thread_t );
315- mp_state_thread_t * ts = m_new_obj (mp_state_thread_t );
316- memset (ts , 0 , sizeof (mp_state_thread_t ));
317264
318265 mp_thread_mutex_lock (& thread_mutex , 1 );
319266
320267 // Find available stack slot
321268 int32_t _slot = mp_thread_find_stack_slot ();
322269 if (_slot < 0 ) {
323270 mp_thread_mutex_unlock (& thread_mutex );
324- m_del_obj (mp_state_thread_t , ts ); // Clean up allocated memory
325271 m_del_obj (mp_thread_t , th );
326272 mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("maximum number of threads reached" ));
327273 }
328274
329- // Create Zephyr thread with K_FOREVER so it stays unscheduled initially
330- // We'll manually wake it and add to ready queue following official Zephyr pattern
275+ // Create Zephyr thread with K_NO_WAIT to start immediately
276+ // This matches the ports/zephyr pattern
331277 th -> id = k_thread_create (
332278 & th -> z_thread ,
333279 mp_thread_stack_array [_slot ],
334280 K_THREAD_STACK_SIZEOF (mp_thread_stack_array [_slot ]),
335281 zephyr_entry ,
336282 entry , arg , NULL ,
337- priority , 0 , K_FOREVER
283+ priority , 0 , K_NO_WAIT
338284 );
339285
340286 if (th -> id == NULL ) {
341287 mp_thread_mutex_unlock (& thread_mutex );
342- m_del_obj (mp_state_thread_t , ts ); // Clean up allocated memory
343288 m_del_obj (mp_thread_t , th );
344289 mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("can't create thread" ));
345290 }
@@ -353,7 +298,6 @@ mp_uint_t mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_s
353298 th -> arg = arg ;
354299 th -> stack = (void * )th -> z_thread .stack_info .start ;
355300 th -> stack_len = th -> z_thread .stack_info .size / sizeof (uintptr_t );
356- th -> thread_state = ts ; // Store pre-allocated thread state
357301 th -> next = thread ;
358302 thread = th ;
359303
@@ -365,18 +309,7 @@ mp_uint_t mp_thread_create_ex(void *(*entry)(void *), void *arg, size_t *stack_s
365309
366310 DEBUG_printf ("Created thread %s (id=%p)\n" , name , th -> id );
367311
368- // Mark thread as not sleeping, then UNLOCK MUTEX before adding to ready queue
369- // This follows official Zephyr's prepare_multithreading() pattern (init.c:467-468)
370- // CRITICAL: Must unlock BEFORE z_ready_thread() to allow context switch to occur
371- // Note: z_ready_thread() uses K_SPINLOCK internally for IRQ protection
372- z_mark_thread_as_not_sleeping (th -> id );
373312 mp_thread_mutex_unlock (& thread_mutex );
374- z_ready_thread (th -> id );
375-
376- // Trigger context switch to give new thread a chance to run
377- // This just sets PendSV which will fire when we return to thread mode
378- extern void mp_zephyr_arch_yield (void );
379- mp_zephyr_arch_yield ();
380313
381314 return (mp_uint_t )th -> id ;
382315}
0 commit comments