GSoC Project Updates, Threads!
Since my last update I have been busy with MicroPython tests- enabling new features and testing them, isolating problematic test cases, sometimes placing appropriate definitions and function calls in the C code.
I traced the failure of builtin_compile to the __globals__ attribute not being available for function objects. Enabling that fixed it.
I also now include the previously ignored float test group, giving us 9 more passing tests.
Turns out that the int_big_div and int_big_mul tests that I mentioned in my previous post were failing because of hardware flow control issues and I fixed it by enabling the IXON termios flag.
The latest update with test cases is that I have 588 passing test cases out of 591 executed. The failing test cases are:
io_iobaseprint_exceptionsys_atexit
I am tracking progress on test cases in this issue. Here is a list of all MicroPython modules that have been enabled so far:
array, builtins, cmath, collections, errno, gc, heapq, io, json, math, os, platform, random, re, struct, sys, time, machine, uctypes
The highlighted ones are either partially enabled, or have a failing testcase.
- io: failing
io_iobasetest - os: no filesystem, so the
fsfunctions are not enabled - re: failing
re_stack_overflowtest - sys:
settrace,ps1,ps2,std{out,in,err}not enabled. failingsys_atexittest - machine: only the bare minimum is enabled as we are using the qemu pc-686 BSP and there is no I2C, SPI, etc.
threads
I have also been able to get threads working on MicroPython. The threads use RTEMS Tasks internally. As for testing threads, I currently have five passing test cases. There are around 8 to 9 more tests but those need locks on the MicroPython side, which is still a work in progress.
I wanted to talk more about how threads are implemented in MicroPython. MicroPython doesn’t have documentation for the _thread module as it is “highly experimental and its API is not yet fully settled”, so I think that makes it a really good topic for a blog post. The thread functions are listed in py/mpthread.h. Ports that implement threads, i.e. the _thread module, need to implement these functions in a mpthreadport.c. Here’s a link to my current mpthreadport.c.
Here’s some debugging output that visualizes the order in which different functions are called:
MicroPython v1.26.0-preview.154.g0dbda0e0c.dirty on 2025-08-20; rtems-i386/pc686 with unknown-cpu
THREAD: get_state
>>> import _thread as th
THREAD: get_state
THREAD: get_state
...
THREAD: get_state
THREAD: get_state
THREAD: get_state
>>> x = lambda: print("thread!")
THREAD: get_state
...
THREAD: get_state
THREAD: get_state
>>> th.start_new_thread(x, ())
THREAD: get_state
...
THREAD: get_state
THREAD: get_state
167837698
THREAD: get_state
THREAD: get_state
>>> THREAD: set_state
THREAD: get_state
THREAD: mutex_lock
THREAD: thread_start
THREAD: get_state
thread!
THREAD: get_state
THREAD: thread_finish
THREAD: get_state
THREAD: get_state
...
>>>
The state for multiple threads is tracked using a linked list, access to which is protected by a mutex. An internal task is created for a new thread using the RTMS task API and a new node is added to the linked list. Here’s the structure of a node:
typedef struct _mp_thread_t {
rtems_id id; // RTEMS task ID
bool ready;
void *arg; // thread-entry args
struct _mp_thread_t *next;
mp_state_thread_t *state; // pointer to this thread's mp state
} mp_thread_t;
I will document the threads implementation in detail when I’m able to get MicroPython locks working.
final work
GSoC coding period ends on 25th August! Here’s a list of action items I am currently working towards:
- implementing MicroPython mutexes (this will help pass all or most of the threads test cases)
- getting the 3 failing testcases to pass, making more skipped tests pass
- preparing a code cleanup branch
- collecting project learnings and milestones for the final work product
Thank you for your time :)