diff options
| author | 2026-10-15 14:33:28 +0330 | |
|---|---|---|
| committer | 2026-10-15 14:33:28 +0330 | |
| commit | 25aa655e5b9464e291d542081ed1cf0f8fd666af (patch) | |
| tree | fb2fa4b3e77914ab00829b39142a2f8cfb3a9d8b /tests/hold/accept | |
| parent | hold blocks: top-level hold { shared let ...; fn ... } monitors; shared value... (diff) | |
hold: fixtures (accept, reject, race, rank order) and tests/drivers/hold_test.py
Diffstat (limited to 'tests/hold/accept')
| -rw-r--r-- | tests/hold/accept/isolated_globals.zc | 18 | ||||
| -rw-r--r-- | tests/hold/accept/monitor.zc | 15 | ||||
| -rw-r--r-- | tests/hold/accept/race.zc | 21 | ||||
| -rw-r--r-- | tests/hold/accept/rank_order.zc | 7 | ||||
| -rw-r--r-- | tests/hold/accept/reentrant.zc | 12 |
5 files changed, 73 insertions, 0 deletions
diff --git a/tests/hold/accept/isolated_globals.zc b/tests/hold/accept/isolated_globals.zc new file mode 100644 index 0000000..08a3e5c --- /dev/null +++ b/tests/hold/accept/isolated_globals.zc @@ -0,0 +1,18 @@ +// expect: 0 3 +// a plain global is each actor's own; only a shared variable of a hold block is seen by all +namespace; +include rt, actor; +typecheck on; +let plain = 0; +hold { shared let seen = 0; fn note() { seen++; return seen; } fn seen_now() { return seen; } } +int work(int n) { plain = plain + n; note(); return plain; } +fn main() { + actor.Actor<int,int>* a = rt.new(actor.Actor<int,int>), b = rt.new(actor.Actor<int,int>), c = rt.new(actor.Actor<int,int>); + a.spawn(work); b.spawn(work); c.spawn(work); + a.send(5); b.send(6); c.send(7); + a.recv(fn(int n) { return 0; }); b.recv(fn(int n) { return 0; }); c.recv(fn(int n) { return 0; }); + a.await(); b.await(); c.await(); + rt.put_n(plain); rt.put_c(' '); rt.put_n(seen_now()); rt.put_c(10); + a.close(); b.close(); c.close(); + return 0; +} diff --git a/tests/hold/accept/monitor.zc b/tests/hold/accept/monitor.zc new file mode 100644 index 0000000..7dfe6f0 --- /dev/null +++ b/tests/hold/accept/monitor.zc @@ -0,0 +1,15 @@ +// expect: 902 +namespace; +include rt; +hold { + shared let c = 5; + shared int[3] hist; + fn bump(int k) { c = c + k; hist[0]++; return c; } + fn twice(int k) { bump(k); return bump(k); } + fn get() { return c * 100 + hist[0]; } +} +fn main() { + twice(2); + rt.put_n(get()); rt.put_c(10); + return 0; +} diff --git a/tests/hold/accept/race.zc b/tests/hold/accept/race.zc new file mode 100644 index 0000000..f7fdb61 --- /dev/null +++ b/tests/hold/accept/race.zc @@ -0,0 +1,21 @@ +// expect: 90000 +// many actors increment one shared counter through a read, then a write; the hold block's lock makes every increment count +namespace; +include rt, actor; +typecheck on; +hold { + shared let count = 0; + fn inc() { let v = count; count = v + 1; return v; } + fn total() { return count; } +} +int work(int n) { let i = 0; while (i < n) { inc(); i++; } return n; } +fn main() { + let i = 0; actor.Actor<int,int>*[?] xs = rt.new(actor.Actor<int,int>*[?]); + while (i < 8) { actor.Actor<int,int>* a = rt.new(actor.Actor<int,int>); a.spawn(work); push(xs, a); i++; } + i = 0; while (i < 8) { xs[i].send(10000); i++; } + work(10000); + i = 0; while (i < 8) { xs[i].recv(fn(int n) { return 0; }); xs[i].await(); i++; } + rt.put_n(total()); rt.put_c(10); + i = 0; while (i < 8) { xs[i].close(); i++; } + return 0; +} diff --git a/tests/hold/accept/rank_order.zc b/tests/hold/accept/rank_order.zc new file mode 100644 index 0000000..9fc903a --- /dev/null +++ b/tests/hold/accept/rank_order.zc @@ -0,0 +1,7 @@ +// expect: 10 +namespace; +include rt; +int gb(); +hold { shared let a; fn ga() { a++; return gb(); } } +hold { shared let b; fn gb() { b++; return b * 10; } } +fn main() { rt.put_n(ga()); rt.put_c(10); return 0; } diff --git a/tests/hold/accept/reentrant.zc b/tests/hold/accept/reentrant.zc new file mode 100644 index 0000000..f0c8293 --- /dev/null +++ b/tests/hold/accept/reentrant.zc @@ -0,0 +1,12 @@ +// expect: 3 1 +// a function of a block calling another of the same block doesn't take the lock again, and a later block may be entered from an earlier one +namespace; +include rt; +int later(); +hold { + shared let depth, calls; + fn inner() { calls++; return depth; } + fn outer() { depth = depth + 1; inner(); inner(); inner(); return calls; } +} +hold { shared let seen; fn later() { seen++; return seen; } } +fn main() { rt.put_n(outer()); rt.put_c(' '); rt.put_n(later()); rt.put_c(10); return 0; } |
