-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Timed lock aquisition #5599
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
Timed lock aquisition #5599
Conversation
# Conflicts: # ports/unix/mpconfigport.h
Thanks for the contribution. In general I'd be supportive of adding this feature. But please see previous discussion about this at #3332, and also try to fix the Travis CI failures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see this getting implemented. 😄
I also like the suggestion of just modifying mp_thread_mutex_lock
instead of adding a new mp_thread_mutex_lock_timed
function. This would simplify things a bit.
ports/esp32/mpconfigport.h
Outdated
@@ -123,6 +123,7 @@ | |||
#define MICROPY_PY_THREAD (1) | |||
#define MICROPY_PY_THREAD_GIL (1) | |||
#define MICROPY_PY_THREAD_GIL_VM_DIVISOR (32) | |||
#define MICROPY_PY_THREAD_TIMEDLOCK (1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to name this after the python feature rather than the posix thread feature, e.g. MICROPY_PY_THREAD_LOCK_TIMEOUT
ports/unix/Makefile
Outdated
@@ -123,6 +123,9 @@ ifeq ($(MICROPY_PY_THREAD),1) | |||
CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 | |||
LDFLAGS_MOD += $(LIBPTHREAD) | |||
endif | |||
ifeq ($(MICROPY_PY_THREAD_TIMEDLOCK),1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new configuration option doesn't really need to be in the Makefile. It could go in mpconfigport.h instead.
The only reason MICROPY_PY_THREAD
is in the Makefile is because it affects the compiler flags.
#ifdef MICROPY_PY_THREAD_TIMEDLOCK | ||
ret = mp_thread_mutex_lock_timed(&self->mutex, timeout); | ||
#else | ||
mp_raise_ValueError("timeout not supported"); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
ports/unix/mpthreadport.c
Outdated
struct timeval _timeval; | ||
struct timezone _timezone; | ||
gettimeofday(&_timeval, &_timezone); | ||
uint32_t _timeout_nano = ((uint32_t) (1e9*timeout)) + 1000 * _timeval.tv_usec; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe do the float conversion like ports/unix/modtime.c
?
struct timeval tv;
mp_float_t val = mp_obj_get_float(arg);
double ipart;
tv.tv_usec = round(modf(val, &ipart) * 1000000);
tv.tv_sec = ipart;
Otherwise, _timeout_nano
probably needs to be uint64_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the updated version I am handling the float
to int
conversion in modthread.c
and passing an int number of milliseconds to mp_thread_mutex_lock_timeout
. See my comment regarding whether one should support int
and float
as timeout argument.
Regarding the overflow issue, the updated version is safe with uint32_t
because _timeout_nano
will always be smaller than 2 seconds.
tests/thread/thread_locktimed2.py
Outdated
@@ -0,0 +1,34 @@ | |||
# test timed _thread lock object using a single thread |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this say "multiple threads" instead of "single thread"?
The one problem I see with this is that
This way the existing calls to |
Thanks for all the great suggestions! |
- label as mp_thread_mutex_lock_timeout - change signature to avoid handling floats on the ports - fixing possible overflow in unix port implementation - removing changes in Makefile for unix port - implementation for cc3200 - no longer raising exception when GIL lock is released
The only failure at Travis CI after the update is the growth in core size in the "bare-arm and minimal ports" build. @dpgeorge I also have a question regarding thread safety in micropython. The first four concurrency tests, the Finally, the other test that fails is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going from ms to us. ms timeout can be too inaccurate if used in clocks or timers that have ms periods. Tradeoff is the maximum timeout encoded with ints. For 32 bits ints should give a maximum of 2147 seconds. 16 bits could be problematic. Perhaps the signature should explicitly have int32_t.
@mcdeoliveira thanks for the effort on this and sorry it got left behind. I'll close this PR for now, but feel free to reopen if you're still interested to work on it and take into account the comment #3332 (comment) |
…n-main Translations update from Hosted Weblate
This PR handles the timeout parameter in
thread_lock_acquire
.It provides a set of compilation flags, tests, and an implementation for the unix and the esp32 ports. Other ports based on freertos should be easy to implement based on the esp32 port, because freertos lock_acquire already handles the timeout parameter. Unfortunately I do not have access to other hardware, so I think it is better to leave to others the task of replicating the functionality on other ports.
Let me just add a word about the relevance of handling the timeout parameter in lock_acquire. The only feature used by the current CPython implementation of threading.py that is nor yet supported by _thread is precisely a call to lock_acquire with a timeout parameter. In fact, a _thread_lock_acquire with timeout is issued in RLock and all subsequent classes in threading.py are based on RLock! Implementing the timeout parameter essentially enables a micropython version of Threading.