-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
zephyr: Make time.sleep() and friends thread safe. #17866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
168d12f
to
8fa64b2
Compare
c85b6b4
to
97f7406
Compare
Currently the delay function is using a single static k_poll_event object which means that multiple threads sleeping at similar times will try to use the same event variable leading to a eventual crash. Signed-off-by: Daniel Campora <danicampora@gmail.com>
97f7406
to
bec9dcf
Compare
Thanks for the PR. I can see why this is needed for the case of more than one thread. But, I did spend quite a bit of effort implementing the existing sleep code, see 916c3fd and d120859 The idea is that it should be possible to tell the zephyr OS to sleep for the maximum possible time, so it could maybe use a low-power sleep. And then the semaphore can wake up the thread early if needed, eg when the user sends ctrl-C, or a I2CTarget IRQ fires and needs to run a Python callback. That's handled by IMO it would be good to keep all those capabilities (sleep for a long time, wake early via a semaphore). The question is how to do that when there are multiple threads using the sleep mechanism. My simple proposal for that would be to have 2 sleep functions: the existing sleep implementation would be used for the main thread, and the implementation in this PR would be used for all other threads. You can select which one via something like this: void mp_hal_delay_ms(mp_uint_t delay_ms) {
if (mp_thread_get_state() == &mp_state_ctx.thread) {
// main thread
mp_hal_wait_sem(NULL, delay_ms);
} else {
// other threads
mp_hal_delay_ms_polling(delay_ms);
}
} (Or maybe you can think of a better way to detect the main thread?) |
Actually, maybe the sleep on non-main threads could be a simple |
@dpgeorge thanks for explaining the reasons of having the original implementation! I will play a bit with your suggestions and update this PR asap. |
@dpgeorge I tried both of the suggestions you made, but they don't produce the desired behaviour. First problem is that
Seems to work better except that the sleep for the main function does not work at all. Need do continue debugging... This is my simple test:
|
Currently the delay function is using a single static k_poll_event object which means that multiple threads sleeping at similar times will try to use the same event variable leading to a eventual crash.
I created a new
mp_hal_delay_ms()
function that is heavily inspired in the one from the ESP32 port.