summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtests/run-tests.py14
-rw-r--r--tests/thread/stress_schedule.py13
-rw-r--r--tests/thread/thread_gc1.py25
-rw-r--r--tests/thread/thread_ident1.py6
-rw-r--r--tests/thread/thread_lock4.py8
-rw-r--r--tests/thread/thread_qstr1.py18
-rw-r--r--tests/thread/thread_shared1.py16
-rw-r--r--tests/thread/thread_sleep1.py19
8 files changed, 93 insertions, 26 deletions
diff --git a/tests/run-tests.py b/tests/run-tests.py
index e5d712303..bbc98cad9 100755
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -562,13 +562,19 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
skip_tests.add("cmdline/repl_sys_ps1_ps2.py")
skip_tests.add("extmod/ssl_poll.py")
- # Some tests shouldn't be run on a PC
- if args.target == "unix":
- # unix build does not have the GIL so can't run thread mutation tests
+ # Skip thread mutation tests on targets that don't have the GIL.
+ if args.target in ("rp2", "unix"):
for t in tests:
if t.startswith("thread/mutate_"):
skip_tests.add(t)
+ # Skip thread tests that require many threads on targets that don't support multiple threads.
+ if args.target == "rp2":
+ skip_tests.add("thread/stress_heap.py")
+ skip_tests.add("thread/thread_lock2.py")
+ skip_tests.add("thread/thread_lock3.py")
+ skip_tests.add("thread/thread_shared2.py")
+
# Some tests shouldn't be run on pyboard
if args.target != "unix":
skip_tests.add("basics/exception_chain.py") # warning is not printed
@@ -987,7 +993,7 @@ the last matching regex is used:
elif args.target in ("renesas-ra"):
test_dirs += ("float", "inlineasm", "renesas-ra")
elif args.target == "rp2":
- test_dirs += ("float", "stress", "inlineasm")
+ test_dirs += ("float", "stress", "inlineasm", "thread")
elif args.target in ("esp8266", "esp32", "minimal", "nrf"):
test_dirs += ("float",)
elif args.target == "wipy":
diff --git a/tests/thread/stress_schedule.py b/tests/thread/stress_schedule.py
index 40191e662..a5d7dc824 100644
--- a/tests/thread/stress_schedule.py
+++ b/tests/thread/stress_schedule.py
@@ -19,6 +19,7 @@ _TIMEOUT_MS = 10000
n = 0 # How many times the task successfully ran.
t = None # Start time of test, assigned here to preallocate entry in globals dict.
+thread_run = True # If the thread should continue running.
def task(x):
@@ -27,7 +28,7 @@ def task(x):
def thread():
- while True:
+ while thread_run:
try:
micropython.schedule(task, None)
except RuntimeError:
@@ -36,13 +37,21 @@ def thread():
for i in range(8):
- _thread.start_new_thread(thread, ())
+ try:
+ _thread.start_new_thread(thread, ())
+ except OSError:
+ # System cannot create a new thead, so stop trying to create them.
+ break
# 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
+# Stop all threads.
+thread_run = False
+time.sleep_ms(20)
+
if n < _NUM_TASKS:
# Not all the tasks were scheduled, likely the scheduler stopped working.
print(n)
diff --git a/tests/thread/thread_gc1.py b/tests/thread/thread_gc1.py
index dd1e64d89..b36ea9d4c 100644
--- a/tests/thread/thread_gc1.py
+++ b/tests/thread/thread_gc1.py
@@ -16,21 +16,34 @@ def thread_entry(n):
data[i] = data[i]
gc.collect()
- # print whether the data remains intact and indicate we are finished
+ # check whether the data remains intact and indicate we are finished
with lock:
- print(list(data) == list(range(256)))
- global n_finished
+ global n_correct, n_finished
+ n_correct += list(data) == list(range(256))
n_finished += 1
lock = _thread.allocate_lock()
-n_thread = 4
+n_thread = 0
+n_thread_max = 4
+n_correct = 0
n_finished = 0
# spawn threads
-for i in range(n_thread):
- _thread.start_new_thread(thread_entry, (10,))
+for _ in range(n_thread_max):
+ try:
+ _thread.start_new_thread(thread_entry, (10,))
+ n_thread += 1
+ except OSError:
+ # System cannot create a new thead, so stop trying to create them.
+ break
+
+# also run the function on this main thread
+thread_entry(10)
+n_thread += 1
# busy wait for threads to finish
while n_finished < n_thread:
pass
+
+print(n_correct == n_finished)
diff --git a/tests/thread/thread_ident1.py b/tests/thread/thread_ident1.py
index 8e106cd31..2a3732eff 100644
--- a/tests/thread/thread_ident1.py
+++ b/tests/thread/thread_ident1.py
@@ -5,7 +5,12 @@
import _thread
+# Initialise variables (also preallocate their spot in the globals dict so the
+# globals dict is not resized while threads are running).
tid = None
+tid_main = None
+new_tid = None
+finished = False
def thread_entry():
@@ -19,7 +24,6 @@ def thread_entry():
tid_main = _thread.get_ident()
print("main", type(tid_main) == int, tid_main != 0)
-finished = False
new_tid = _thread.start_new_thread(thread_entry, ())
while not finished:
diff --git a/tests/thread/thread_lock4.py b/tests/thread/thread_lock4.py
index 97c3dc538..b424ee3d0 100644
--- a/tests/thread/thread_lock4.py
+++ b/tests/thread/thread_lock4.py
@@ -36,14 +36,18 @@ output_lock = _thread.allocate_lock()
# spawn threads to do the jobs
for i in range(4):
- _thread.start_new_thread(thread_entry, ())
+ try:
+ _thread.start_new_thread(thread_entry, ())
+ except OSError:
+ # System cannot create a new thead, so stop trying to create them.
+ break
# wait for the jobs to complete
while True:
with jobs_lock:
if len(output) == n_jobs:
break
- time.sleep(1)
+ time.sleep(0)
# sort and print the results
output.sort(key=lambda x: x[0])
diff --git a/tests/thread/thread_qstr1.py b/tests/thread/thread_qstr1.py
index f184d2a58..96f12c5d8 100644
--- a/tests/thread/thread_qstr1.py
+++ b/tests/thread/thread_qstr1.py
@@ -24,16 +24,26 @@ def th(base, n):
lock = _thread.allocate_lock()
-n_thread = 4
+n_thread = 0
+n_thread_max = 4
n_finished = 0
n_qstr_per_thread = 100 # make 1000 for a more stressful test (uses more heap)
# spawn threads
-for i in range(n_thread):
- _thread.start_new_thread(th, (i * n_qstr_per_thread, n_qstr_per_thread))
+for _ in range(n_thread_max):
+ try:
+ _thread.start_new_thread(th, (n_thread * n_qstr_per_thread, n_qstr_per_thread))
+ n_thread += 1
+ except OSError:
+ # System cannot create a new thead, so stop trying to create them.
+ break
+
+# also run the function on this main thread
+th(n_thread * n_qstr_per_thread, n_qstr_per_thread)
+n_thread += 1
# wait for threads to finish
while n_finished < n_thread:
- time.sleep(1)
+ time.sleep(0)
print("pass")
diff --git a/tests/thread/thread_shared1.py b/tests/thread/thread_shared1.py
index 582b01fc3..251e26fae 100644
--- a/tests/thread/thread_shared1.py
+++ b/tests/thread/thread_shared1.py
@@ -18,15 +18,25 @@ def thread_entry(n, tup):
lock = _thread.allocate_lock()
-n_thread = 2
+n_thread = 0
+n_thread_max = 2
n_finished = 0
# the shared data structure
tup = (1, 2, 3, 4)
# spawn threads
-for i in range(n_thread):
- _thread.start_new_thread(thread_entry, (100, tup))
+for _ in range(n_thread_max):
+ try:
+ _thread.start_new_thread(thread_entry, (100, tup))
+ n_thread += 1
+ except OSError:
+ # System cannot create a new thead, so stop trying to create them.
+ break
+
+# also run the function on this main thread
+thread_entry(100, tup)
+n_thread += 1
# busy wait for threads to finish
while n_finished < n_thread:
diff --git a/tests/thread/thread_sleep1.py b/tests/thread/thread_sleep1.py
index add9b02f1..36f775d1f 100644
--- a/tests/thread/thread_sleep1.py
+++ b/tests/thread/thread_sleep1.py
@@ -12,7 +12,8 @@ else:
import _thread
lock = _thread.allocate_lock()
-n_thread = 4
+n_thread = 0
+n_thread_max = 4
n_finished = 0
@@ -24,10 +25,20 @@ def thread_entry(t):
n_finished += 1
-for i in range(n_thread):
- _thread.start_new_thread(thread_entry, (10 * i,))
+# spawn threads
+for _ in range(n_thread_max):
+ try:
+ _thread.start_new_thread(thread_entry, (10 * n_thread,))
+ n_thread += 1
+ except OSError:
+ # System cannot create a new thead, so stop trying to create them.
+ break
+
+# also run the function on this main thread
+thread_entry(10 * n_thread)
+n_thread += 1
# wait for threads to finish
while n_finished < n_thread:
sleep_ms(100)
-print("done", n_thread)
+print("done")