summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2025-07-13 22:49:15 +1000
committerDamien George <damien@micropython.org>2025-07-23 11:37:00 +1000
commitb070765427283fd994f217b8c7601ef9b1f9a37a (patch)
treeb0977907d1a1267348e75da512f8c3b68a476f49
parentb15065b95e24a939e09289ee18ce84579605b929 (diff)
tests/thread: Allow thread tests to pass with the native emitter.
The native emitter will not release/bounce the GIL when running code, so if it runs tight loops then no other threads get a chance to run (if the GIL is enabled). So for the thread tests, explicitly include a call to `time.sleep(0)` (or equivalent) to bounce the GIL and give other threads a chance to run. For some tests (eg `thread_coop.py`) the whole point of the test is to test that the GIL is correctly bounced. So for those cases force the use of the bytecode emitter for the busy functions. Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--tests/thread/mutate_bytearray.py3
-rw-r--r--tests/thread/mutate_dict.py3
-rw-r--r--tests/thread/mutate_instance.py3
-rw-r--r--tests/thread/mutate_list.py3
-rw-r--r--tests/thread/mutate_set.py3
-rw-r--r--tests/thread/stress_recurse.py3
-rw-r--r--tests/thread/stress_schedule.py4
-rw-r--r--tests/thread/thread_coop.py3
-rw-r--r--tests/thread/thread_exc1.py3
-rw-r--r--tests/thread/thread_gc1.py3
-rw-r--r--tests/thread/thread_ident1.py3
-rw-r--r--tests/thread/thread_lock3.py3
-rw-r--r--tests/thread/thread_shared1.py3
-rw-r--r--tests/thread/thread_shared2.py3
-rw-r--r--tests/thread/thread_stacksize1.py3
-rw-r--r--tests/thread/thread_stdin.py3
16 files changed, 34 insertions, 15 deletions
diff --git a/tests/thread/mutate_bytearray.py b/tests/thread/mutate_bytearray.py
index b4664781a..7116d291c 100644
--- a/tests/thread/mutate_bytearray.py
+++ b/tests/thread/mutate_bytearray.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
# the shared bytearray
@@ -36,7 +37,7 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
# check bytearray has correct contents
print(len(ba))
diff --git a/tests/thread/mutate_dict.py b/tests/thread/mutate_dict.py
index 3777af662..dd5f69e6c 100644
--- a/tests/thread/mutate_dict.py
+++ b/tests/thread/mutate_dict.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
# the shared dict
@@ -38,7 +39,7 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
# check dict has correct contents
print(sorted(di.items()))
diff --git a/tests/thread/mutate_instance.py b/tests/thread/mutate_instance.py
index 306ad91c9..63f7fb1e2 100644
--- a/tests/thread/mutate_instance.py
+++ b/tests/thread/mutate_instance.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
@@ -40,7 +41,7 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
# check user instance has correct contents
print(user.a, user.b, user.c)
diff --git a/tests/thread/mutate_list.py b/tests/thread/mutate_list.py
index 6f1e88125..d7398a2f1 100644
--- a/tests/thread/mutate_list.py
+++ b/tests/thread/mutate_list.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
# the shared list
@@ -39,7 +40,7 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
# check list has correct contents
li.sort()
diff --git a/tests/thread/mutate_set.py b/tests/thread/mutate_set.py
index 2d9a3e0ce..7dcefa1d1 100644
--- a/tests/thread/mutate_set.py
+++ b/tests/thread/mutate_set.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
# the shared set
@@ -33,7 +34,7 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
# check set has correct contents
print(sorted(se))
diff --git a/tests/thread/stress_recurse.py b/tests/thread/stress_recurse.py
index 73b3a40f3..ec8b43fe8 100644
--- a/tests/thread/stress_recurse.py
+++ b/tests/thread/stress_recurse.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
@@ -24,5 +25,5 @@ _thread.start_new_thread(thread_entry, ())
# busy wait for thread to finish
while not finished:
- pass
+ time.sleep(0)
print("done")
diff --git a/tests/thread/stress_schedule.py b/tests/thread/stress_schedule.py
index 97876f0f7..362d71aa1 100644
--- a/tests/thread/stress_schedule.py
+++ b/tests/thread/stress_schedule.py
@@ -27,6 +27,8 @@ def task(x):
n += 1
+# This function must always use the bytecode emitter so it bounces the GIL when running.
+@micropython.bytecode
def thread():
while thread_run:
try:
@@ -46,7 +48,7 @@ for i in range(8):
# Wait up to 10 seconds for 10000 tasks to be scheduled.
t = time.ticks_ms()
while n < _NUM_TASKS and time.ticks_diff(time.ticks_ms(), t) < _TIMEOUT_MS:
- pass
+ time.sleep(0)
# Stop all threads.
thread_run = False
diff --git a/tests/thread/thread_coop.py b/tests/thread/thread_coop.py
index aefc4af07..85cda789c 100644
--- a/tests/thread/thread_coop.py
+++ b/tests/thread/thread_coop.py
@@ -7,6 +7,7 @@
import _thread
import sys
from time import ticks_ms, ticks_diff, sleep_ms
+import micropython
done = False
@@ -21,6 +22,8 @@ if sys.platform in ("win32", "linux", "darwin"):
MAX_DELTA = 100
+# This function must always use the bytecode emitter so the VM can bounce the GIL when running.
+@micropython.bytecode
def busy_thread():
while not done:
pass
diff --git a/tests/thread/thread_exc1.py b/tests/thread/thread_exc1.py
index cd8774092..cd6599983 100644
--- a/tests/thread/thread_exc1.py
+++ b/tests/thread/thread_exc1.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
@@ -34,5 +35,5 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
print("done")
diff --git a/tests/thread/thread_gc1.py b/tests/thread/thread_gc1.py
index b36ea9d4c..45c17cc17 100644
--- a/tests/thread/thread_gc1.py
+++ b/tests/thread/thread_gc1.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import gc
import _thread
@@ -44,6 +45,6 @@ n_thread += 1
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
print(n_correct == n_finished)
diff --git a/tests/thread/thread_ident1.py b/tests/thread/thread_ident1.py
index 2a3732eff..08cfd3eb3 100644
--- a/tests/thread/thread_ident1.py
+++ b/tests/thread/thread_ident1.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
@@ -27,6 +28,6 @@ print("main", type(tid_main) == int, tid_main != 0)
new_tid = _thread.start_new_thread(thread_entry, ())
while not finished:
- pass
+ time.sleep(0)
print("done", type(new_tid) == int, new_tid == tid)
diff --git a/tests/thread/thread_lock3.py b/tests/thread/thread_lock3.py
index a927dc682..c5acfa21b 100644
--- a/tests/thread/thread_lock3.py
+++ b/tests/thread/thread_lock3.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
lock = _thread.allocate_lock()
@@ -26,4 +27,4 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
diff --git a/tests/thread/thread_shared1.py b/tests/thread/thread_shared1.py
index 251e26fae..c2e33abce 100644
--- a/tests/thread/thread_shared1.py
+++ b/tests/thread/thread_shared1.py
@@ -2,6 +2,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
@@ -40,5 +41,5 @@ n_thread += 1
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
print(tup)
diff --git a/tests/thread/thread_shared2.py b/tests/thread/thread_shared2.py
index a1223c2b9..4ce9057ca 100644
--- a/tests/thread/thread_shared2.py
+++ b/tests/thread/thread_shared2.py
@@ -3,6 +3,7 @@
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
+import time
import _thread
@@ -31,5 +32,5 @@ for i in range(n_thread):
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
print(lst)
diff --git a/tests/thread/thread_stacksize1.py b/tests/thread/thread_stacksize1.py
index 140d165cb..75e1da964 100644
--- a/tests/thread/thread_stacksize1.py
+++ b/tests/thread/thread_stacksize1.py
@@ -3,6 +3,7 @@
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd
import sys
+import time
import _thread
# different implementations have different minimum sizes
@@ -51,5 +52,5 @@ _thread.stack_size()
# busy wait for threads to finish
while n_finished < n_thread:
- pass
+ time.sleep(0)
print("done")
diff --git a/tests/thread/thread_stdin.py b/tests/thread/thread_stdin.py
index a469933f1..498b0a3a2 100644
--- a/tests/thread/thread_stdin.py
+++ b/tests/thread/thread_stdin.py
@@ -5,6 +5,7 @@
# This is a regression test for https://github.com/micropython/micropython/issues/15230
# on rp2, but doubles as a general property to test across all ports.
import sys
+import time
import _thread
try:
@@ -38,7 +39,7 @@ StdinWaiter().wait_stdin(1000)
# have run yet. The actual delay is <20ms but spinning here instead of
# sleep(0.1) means the test can run on MP builds without float support.
while not thread_waiter.is_done():
- pass
+ time.sleep(0)
# The background thread should have completed its wait by now.
print(thread_waiter.is_done())