diff options
Diffstat (limited to 'testsuite/tests/lib-systhreads/testyield.ml')
-rw-r--r-- | testsuite/tests/lib-systhreads/testyield.ml | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/testsuite/tests/lib-systhreads/testyield.ml b/testsuite/tests/lib-systhreads/testyield.ml new file mode 100644 index 0000000000..30e70ce946 --- /dev/null +++ b/testsuite/tests/lib-systhreads/testyield.ml @@ -0,0 +1,51 @@ +(* TEST + (* Test that yielding between busy threads reliably triggers a thread + switch. *) + include systhreads + * not-windows + ** bytecode + ** native +*) + +let threads = 4 + +let are_ready = ref 0 + +let yields = ref 0 + +let iters = 50000 + +let last = ref (-1) + +let report thread run_length = + (* The below loop tests how many times in a row a loop that calls yield runs + without changing threads. Ideally the answer would *always* be one, but + it's not clear we can reliably guarantee that unless nothing else ever + drops the Ocaml lock, so instead just rely on it being small. *) + if run_length > 3 + then Printf.printf "Thread %d ran %d consecutive iters\n" thread run_length + + +let threads = + List.init threads (Thread.create (fun i -> + incr are_ready; + (* Don't make any progress until all threads are spawned and properly + contending for the Ocaml lock. *) + while !are_ready < threads do + Thread.yield () + done; + let consecutive = ref 0 in + while !yields < iters do + incr yields; + last := i; + Thread.yield (); + incr consecutive; + if not (!last = i) + then ( + report i !consecutive; + consecutive := 0) + done; + if !consecutive > 0 then report i !consecutive; + ));; + +List.iter Thread.join threads |