← index #11837PR #18685
Likely Duplicate · high · value 0.171
QUERY · ISSUE

Zephyr port: async event loop implementation starves CPU

openby bogdanmopened 2023-06-21updated 2023-06-22
enhancementport-zephyr

When using asyncio in MicroPython, the event loop implementation (asyncio.run) ends up polling Python objects in a queue. The polling code does this (extmod/modselect.c:poll_poll_internal):

...
    mp_uint_t start_tick = mp_hal_ticks_ms();
    mp_uint_t n_ready;
    for (;;) {
        // poll the objects
        n_ready = poll_map_poll(&self->poll_map, NULL);
        if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
            break;
        }
        MICROPY_EVENT_POLL_HOOK
    }
...

The for(;;) loop above is a busy wait loop. In the Zephyr port, it consumes a lot of CPU time and it starves other threads. Even when MICROPY_EVENT_POOL_HOOK is set to k_yield (and thus the loop gives control back to the OS scheduler after each iteration) the code will still take most of the CPU time. Setting MICROPY_EVENT_POOL_HOOK to something like k_msleep(100) (which waits 100ms before running another iteration of the loop) fixes the starving issue, but it delays the Python thread for no good reason.

I have a possible solution for this, but please let me know first if there is interest to move this forward, since lately I got the impression that the Zephyr port isn't exactly a "fist class citizen" in the world of MicroPython ports.

CANDIDATE · PULL REQUEST

zephyr: Convert port to use new event waiting functions.

openby dpgeorgeopened 2026-01-14updated 2026-02-08
port-zephyr

Summary

This PR converts the zephyr port to use the new event waiting mechanism, with the MICROPY_INTERNAL_WFE macro.

As part of this, the mp_hal_wait_sem() function is updated so it can exit early when an event occurs. That allows it to be used by MICROPY_INTERNAL_WFE to implement efficient waiting, so calls like mp_event_wait_indefinite() will actually suspend the thread until an event wakes it.

Testing

Tested on frdm_k64f, running the full test suite. There were no regressions. Note that the new event logic in machine_uart.c is tested by tests/extmod/machine_uart_tx.py (by using a custom target_wiring.py file).

Trade-offs and Alternatives

When threading is enabled mp_hal_wait_sem() does not work correctly due to global state. But that's the topic of a separate PR #17866.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied