Skip to content

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

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

Open
dlech opened this issue Sep 26, 2017 · 8 comments · May be fixed by #15099
Open

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

dlech opened this issue Sep 26, 2017 · 8 comments · May be fixed by #15099
Labels
py-core Relates to py/ directory in source

Comments

@dlech
Copy link
Contributor

dlech commented Sep 26, 2017

// TODO support timeout arg


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.

@dpgeorge
Copy link
Member

Implementing the timeout parameter requires 2 parts:

  1. accepting the parameter in py/modthread.c and passing it through to the underlying port implementation (this is platform independent)
  2. implementing a timed mutex lock for each platform (this is platform dependent)

Part 2 is the more difficult part. For the unix port the easiest way to do it would be to convert the use of pthread mutexs to semaphores and use sem_timedwait.

An alternative to the above is to implement in a naive way a port-independent timeout via a polling loop in thread_lock_acquire(): if a timeout is specified then keep trying to lock the mutex in a loop until the timeout expires. This isn't very efficient in terms of thread scheduling but will work for all ports and is relatively easy to implement.

@pfalcon pfalcon changed the title timeout parameter is not implemented in _thread.allocate_lock() _thread: timeout parameter is not implemented in _thread.allocate_lock() Nov 3, 2017
@nevercast
Copy link
Contributor

An alternative to the above is to implement in a naive way a port-independent timeout via a polling loop in thread_lock_acquire(): if a timeout is specified then keep trying to lock the mutex in a loop until the timeout expires. This isn't very efficient in terms of thread scheduling but will work for all ports and is relatively easy to implement.

I would like to avoid that approach as it does give very poor performance which can be difficult to debug if you aren't expecting native sleep functions to busy loop.

Part 2 is the more difficult part

Can we create an API for this if one is not already implemented, I would like to consider implementing this on ESP32 using the constructs already available in FreeRTOS.

@dpgeorge
Copy link
Member

Can we create an API for this if one is not already implemented, I would like to consider implementing this on ESP32 using the constructs already available in FreeRTOS.

I'd suggest to change (at the C level) the existing mp_thread_mutex_lock(mutex, wait) function to take a timeout value instead of the wait argument, eg mp_thread_mutex_lock(mutex, timeout). If timeout=-1 then it waits forever, if timeout=0 then it doesn't wait at all (existing behaviour for wait=1 and wait=0), and any positive timeout value would be the time to wait for the mutex.

Would need to choose units for this timeout argument. CPython's _thread.acquire accepts a floating point value in seconds. But making timeout in units of milliseconds (at the C level) would be more consistent with other existing things (like select.poll). Going with milliseconds would limit the range (at the C level) to about 49 days (32 bit value) which is probably acceptable.

@dpgeorge dpgeorge changed the title _thread: timeout parameter is not implemented in _thread.allocate_lock() _thread: timeout parameter is not implemented in Lock.acquire() Apr 20, 2020
@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Apr 20, 2020
tannewt pushed a commit to tannewt/circuitpython that referenced this issue Aug 27, 2020
@dpgeorge
Copy link
Member

To move forward on this I would suggest:

  • for all ports that implement it, to change mp_thread_mutex_lock() to support timed acquisition (either as a uint64_t to support high resolution and long times, or 2x uint32_t, a second and microsecond value)
  • unconditionally (ie no config option) support the timeout parameter to Lock.acquire()

A good start on doing this has been made in #5599 but it needs further work.

@water5
Copy link

water5 commented Dec 13, 2021

It already implemented on pycom?
https://docs.pycom.io/firmwareapi/micropython/_thread/#lockacquirewaitflag1-timeout-1

I have not a pycom board to verify that.

@robert-hh
Copy link
Contributor

Question about the Pycom flavor of Micropython are better asked in the Pycom repository of forum.

@water5
Copy link

water5 commented Dec 13, 2021

MicroPython /ports/cc3200 have WIPY board, their MicroPython implement have big difference?

@robert-hh
Copy link
Contributor

The cc3200 WiPy board is the WiPy 1.x. The board is not sold any more since a while. If you have such a board, then you can try yourself whether that is implemented. If you do not have that board, you will most likely not get one. Although some vendors still sell it to people, expecting to get a WiPy 3 board, ESP32 based.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants