← index #3332PR #15099
Duplicate · high · value 3.182
QUERY · ISSUE

_thread: timeout parameter is not implemented in Lock.acquire()

openby dlechopened 2017-09-26updated 2024-08-28
py-core

https://github.com/micropython/micropython/blob/62849b7010abffb7b0a9c9875930efe7cb77519c/py/modthread.c#L69


Background:

I'm looking for a way to implement a cancelable timeout on Linux, e.g something like threading.Timer from the standard library.

Being on Linux, I'm thinking of trying a timerfd with uasyncio instead. But if implementing the timeout parameter here is not too hard, I could give it a try. It looks to be platform dependent though, so it might be beyond my capabilities.

CANDIDATE · PULL REQUEST

py/_thread: Add support for lock.acquire timeout.

openby DvdGiessenopened 2024-05-22updated 2026-03-25
py-core

Fixes #3332. Based on previous work in #5599 and #8932.

Differences to previous PR's:

  • Uses a per-port resolution
    • This prevents us from always converting to microseconds and back on ports that don't have that level of precision, no longer limiting the maximum timeout.
    • Also used to implement _thread.TIMEOUT_MAX (see CPython docs), which in turn is used to raise an OverflowError if a too large timeout is given.
  • Maintains the MICROPY_PY_THREAD_LOCK_TIMEOUT feature flag from @mcdeoliveira, since some ports do not support timeouts yet.
    • Adds POSIX feature flags check since apparently my MacOS system doesn't support pthread_mutex_timedlock (see here).
    • This flag also controls the availability of _thread.TIMEOUT_MAX, which is used in the tests to determine whether timeouts are supported or the test should be skipped.
  • Takes into account comments from @dpgeorge in https://github.com/micropython/micropython/issues/3332#issuecomment-971109197
    • Modifies the existing mp_thread_mutex_lock to add full timeout support instead of adding an extra function.
    • Uses int64_t for the timeout value (see note below).

It still has some open issues / questions:

  • The code for adding an constant float/int to the _thread class is wrong. Looking at other examples like math.PI and sys.maxsize, it looks like currently all these are defined in the global obj.h/objint.h so they can have separate implementations for each supported storage format?
    • Even nicer would be if we had some helpers / defines to make it easier to define large integer / float constants, without having to put them into the global int/float implemenation files. But that's probably out of scope for this PR.
  • I've switched to int64_t because on the Unix port the max timeout would otherwise be a mere 35 minutes. However on many other ports the resolution method (see above) already allows for longer timeouts. We could add another per-port define for the type so we could use a smaller type on some ports? I'm not sure if that would be a meaningful improvement for the smaller microcontrollers.
  • The TIMEOUT_MAX value is not entirely accurate; it does for example not take into account the mp_int_t size limit, or on the Unix port the fact that we cannot use the full uint32 range because the current time should be subtracted.

And it needs testing on all the platforms; I've don't have hardware for all of them.

Feedback is welcomed!

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