summaryrefslogtreecommitdiffstatshomepage
path: root/tests/thread
Commit message (Collapse)AuthorAge
* shared/tinyusb: Only run TinyUSB on the main thread if GIL is disabled.Angus Gratton2024-09-19
| | | | | | | | | | | | | | | | | | | If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes #15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
* tests/thread: Adapt stress_aes.py to run on zephyr.danicampora2024-09-06
| | | | Signed-off-by: danicampora <danicampora@gmail.com>
* esp32/mpthreadport: Fix uneven GIL allocation between Python threads.Angus Gratton2024-07-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Explicitly yield each time a thread mutex is unlocked. Key to understanding this bug is that Python threads run at equal RTOS priority, and although ESP-IDF FreeRTOS (and I think vanilla FreeRTOS) scheduler will round-robin equal priority tasks in the ready state it does not make a similar guarantee for tasks moving between ready and waiting. The pathological case of this bug is when one Python thread task is busy (i.e. never blocks) it will hog the CPU more than expected, sometimes for an unbounded amount of time. This happens even though it periodically unlocks the GIL to allow another task to run. Assume T1 is busy and T2 is blocked waiting for the GIL. T1 is executing and hits a condition to yield execution: 1. T1 calls MP_THREAD_GIL_EXIT 2. FreeRTOS sees T2 is waiting for the GIL and moves it to the Ready list (but does not preempt, as T2 is same priority, so T1 keeps running). 3. T1 immediately calls MP_THREAD_GIL_ENTER and re-takes the GIL. 4. Pre-emptive context switch happens, T2 wakes up, sees GIL is not available, and goes on the waiting list for the GIL again. To break this cycle step 4 must happen before step 3, but this may be a very narrow window of time so it may not happen regularly - and quantisation of the timing of the tick interrupt to trigger a context switch may mean it never happens. Yielding at the end of step 2 maximises the chance for another task to run. Adds a test that fails on esp32 before this fix and passes afterwards. Fixes issue #15423. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
* tests/thread/stress_aes.py: Fix logic waiting for finished threads.Damien George2024-07-05
| | | | | | | | Because the main thread executes `thread_entry()` it means there's an additional one added to `count`, so the test must wait for the count to reach `n_thread + 1`. Signed-off-by: Damien George <damien@micropython.org>
* rp2: Fix recursive atomic sections when core1 is active.Angus Gratton2024-06-25
| | | | | | | | | | | | | | | | | | | | mp_thread_begin_atomic_section() is expected to be recursive (i.e. for nested machine.disable_irq() calls, or if Python code calls disable_irq() and then the Python runtime calls mp_handle_pending() which also enters an atomic section to check the scheduler state). On rp2 when not using core1 the atomic sections are recursive. However when core1 was active (i.e. _thread) then there was a bug that caused the core to live-lock if an atomic section recursed. Adds a test case specifically for mutual exclusion and recursive atomic sections when using two threads. Without this fix the test immediately hangs on rp2. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
* tests/thread: Re-enable GC before stress_schedule test ends.Angus Gratton2024-06-21
| | | | | | | Otherwise GC stays disabled (not re-enabled by soft reset) and later test runs fail with MemoryError. Signed-off-by: Angus Gratton <angus@redyak.com.au>
* tests/thread: Add a test for accuracy of sleep within a thread.Damien George2024-01-05
| | | | | | | | | | | The existing thread_sleep1.py test only tests execution, not accuracy, of time.sleep. Also the existing test only tests sleep(0) on targets like rp2 that can only create a single thread. The new test in this commit checks for timing accuracy on the main thread and one other thread when they run at the same time. Signed-off-by: Damien George <damien@micropython.org>
* tests/thread: Adjust thread tests so most are able to run on rp2 port.Damien George2024-01-05
| | | | | | | | | | | | | | | | | | | | | | | | The aim of this commit is to make it so that the existing thread tests can be used to test the _thread module on the rp2 port. The rp2 port only allows up to one thread to be created at a time, and does not have the GIL enabled. The following changes have been made: - run-tests.py skips mutation tests on rp2, because there's no GIL. - run-tests.py skips other tests on rp2 that require more than one thread. - The tests stop trying to start a new thread after there is an OSError, which indicates that the system cannot create more threads. - Some of these tests also now run the test function on the main thread, not just the spawned threads. - In some tests the output printing is adjusted so it's the same regardless of how many threads were spawned. - Some time.sleep(1) are replaced with time.sleep(0) to make the tests run a little faster (finish sooner when the work is done). For the most part the tests are unchanged for existing platforms like esp32 and unix. Signed-off-by: Damien George <damien@micropython.org>
* py/modthread: Return thread id from start_new_thread().David Lechner2023-09-03
| | | | | | | | | | | | | | | | In CPython, `_thread.start_new_thread()` returns an ID that is the same ID that is returned by `_thread.get_ident()`. The current MicroPython implementation of `_thread.start_new_thread()` always returns `None`. This modifies the required functions to return a value. The native thread id is returned since this can be used for interop with other functions, for example, `pthread_kill()` on *nix. `_thread.get_ident()` is also modified to return the native thread id so that the values match and avoids the need for a separate `native_id` attribute. Fixes issue #12153. Signed-off-by: David Lechner <david@pybricks.com>
* tests: Replace umodule with module everywhere.Jim Mussared2023-06-08
| | | | | | This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* all: Fix spelling mistakes based on codespell check.Damien George2023-04-27
| | | | Signed-off-by: Damien George <damien@micropython.org>
* top: Update Python formatting to black "2023 stable style".Jim Mussared2023-02-02
| | | | | | See https://black.readthedocs.io/en/stable/the_black_code_style/index.html Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
* tests/thread: Use less resources for stress_aes if settrace enabled.Damien George2022-05-17
| | | | Signed-off-by: Damien George <damien@micropython.org>
* tests/thread: Make exc1,exit1,exit2,stacksize1,start1 tests run on rp2.Damien George2021-05-10
| | | | | | | | | | The RP2040 has 2 cores and supports running at most 2 Python threads (the main one plus another), and will raise OSError if a thread cannot be created because core1 is already in use. This commit adjusts some thread tests to be robust against such OSError's. These tests now pass on rp2 boards. Signed-off-by: Damien George <damien@micropython.org>
* py/gc: Make gc_lock_depth have a count per thread.Damien George2021-05-10
| | | | | | | | | | | | | | | | | | | | | | | This commit makes gc_lock_depth have one counter per thread, instead of one global counter. This makes threads properly independent with respect to the GC, in particular threads can now independently lock the GC for themselves without locking it for other threads. It also means a given thread can run a hard IRQ without temporarily locking the GC for all other threads and potentially making them have MemoryError exceptions at random locations (this really only occurs on MCUs with multiple cores and no GIL, eg on the rp2 port). The commit also removes protection of the GC lock/unlock functions, which is no longer needed when the counter is per thread (and this also fixes the cas where a hard IRQ calling gc_lock() may stall waiting for the mutex). It also puts the check for `gc_lock_depth > 0` outside the GC mutex in gc_alloc, gc_realloc and gc_free, to potentially prevent a hard IRQ from waiting on a mutex if it does attempt to allocate heap memory (and putting the check outside the GC mutex is now safe now that there is a gc_lock_depth per thread). Signed-off-by: Damien George <damien@micropython.org>
* tests/thread: Make stress_aes.py test run on bare-metal ports.Damien George2021-05-08
| | | | | | | This is a long-running test, so make it run in reasonable time on slower, bare-metal ports. Signed-off-by: Damien George <damien@micropython.org>
* tests/thread: Make stress_create.py test run on esp32.Damien George2021-05-08
| | | | | | | The esp32 port needs to be idle for finished threads and their resources to be freed up. Signed-off-by: Damien George <damien@micropython.org>
* esp32/mpthreadport: Use binary semaphore instead of mutex.Damien George2021-05-08
| | | | | | | So a lock can be acquired on one Python thread and then released on another. A test for this is added. Signed-off-by: Damien George <damien@micropython.org>
* tests/thread/stress_schedule.py: Assign globals before running test.Damien George2020-10-28
| | | | | | | | When threading is enabled without the GIL then there can be races between the threads accessing the globals dict. Avoid this issue by making sure all globals variables are allocated before starting the threads. Signed-off-by: Damien George <damien@micropython.org>
* all: Rename "sys" module to "usys".stijn2020-09-04
| | | | | | | | | This is consistent with the other 'micro' modules and allows implementing additional features in Python via e.g. micropython-lib's sys. Note this is a breaking change (not backwards compatible) for ports which do not enable weak links, as "import sys" must now be replaced with "import usys".
* tests/thread/thread_stacksize1.py: Increase stack size for CPython.yangfl2020-05-05
| | | | | | | | | | | | On arm64 with CPython: >>> _thread.stack_size(32*1024) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: size not valid: 32768 bytes So increase the CPython value in the test to 512k so it runs on more systems (on modern Linux the default stack size is usually 8MB).
* py/scheduler: Add assert that scheduler is locked when unlocking.Jim Mussared2020-04-13
| | | | | And add a test that shows how this can happen when multiple threads are accessing the scheduler, which fails if atomic sections are not used.
* tests: Format all Python code with black, except tests in basics subdir.David Lechner2020-03-30
| | | | | | | | | | This adds the Python files in the tests/ directory to be formatted with ./tools/codeformat.py. The basics/ subdirectory is excluded for now so we aren't changing too much at once. In a few places `# fmt: off`/`# fmt: on` was used where the code had special formatting for readability or where the test was actually testing the specific formatting.
* py/modthread: Raise RuntimeError in release() if lock is not acquired.Damien George2017-06-14
|
* various: Spelling fixesVille Skyttä2017-05-29
|
* tests/thread: Add stress-test for creating many threads.Damien George2017-02-15
|
* tests/thread: Replace busy waiting loops with a loop that sleeps.Damien George2017-02-15
| | | | | | Depending on the thread scheduler, a busy-wait loop can hog the CPU and make the tests very slow. So convert such loops to loops that have an explicit sleep, allowing the worker threads to do their job.
* tests/thread: Fix stack size test so tests run reliably on baremetal.Damien George2017-02-01
|
* tests/thread: Make thread_exc2 runable on baremetal.Damien George2017-01-31
|
* tests/thread: Improve modthread.c test coverage.Rami Ali2016-12-29
|
* tests/thread: Allow some tests to run on ports with not much heap.Damien George2016-06-28
|
* tests/thread: Allow thread_sleep1 to run without floating point.Damien George2016-06-28
|
* tests/thread: Make sure that thread tests don't rely on floating point.Damien George2016-06-28
|
* tests/thread: Make stack-size test run correctly and reliable on uPy.Damien George2016-06-28
|
* tests/thread: Add test for concurrent mutating of user instance.Damien George2016-06-28
|
* tests/thread: Add test for concurrent interning of strings.Damien George2016-06-28
| | | | Qstr code accesses global state and needs to be made thread safe.
* tests/thread: Add tests that mutate shared objects.Damien George2016-06-28
| | | | Tests concurrent mutating access to: list, dict, set, bytearray.
* tests/thread: Rename thread_stress_XXX.py to stress_XXX.py.Damien George2016-06-28
|
* tests/thread: Add tests for running GC within a thread, and heap stress.Damien George2016-06-28
|
* tests/thread: Remove need to sleep to wait for completion in some tests.Damien George2016-06-28
| | | | | | Use a lock and a counter instead, and busy wait for all threads to complete. This makes test run faster and they no longer rely on the time module.
* tests: Add 3 more tests for _thread module.Damien George2016-06-28
|
* tests: Add tests for _thread module.Damien George2016-06-28
Includes functionality and stress tests.