micropython / micropython

MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems
https://micropython.org
Other
19.09k stars 7.63k forks source link

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

Open dlech opened 6 years ago

dlech commented 6 years ago

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.

dpgeorge commented 6 years ago

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.

nevercast commented 4 years ago

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 commented 4 years ago

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 commented 2 years ago

To move forward on this I would suggest:

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

water5 commented 2 years ago

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 commented 2 years ago

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

water5 commented 2 years ago

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

robert-hh commented 2 years ago

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.