summaryrefslogtreecommitdiff
path: root/tests/features/test_concurrency_suite.zc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/features/test_concurrency_suite.zc')
-rw-r--r--tests/features/test_concurrency_suite.zc98
1 files changed, 98 insertions, 0 deletions
diff --git a/tests/features/test_concurrency_suite.zc b/tests/features/test_concurrency_suite.zc
new file mode 100644
index 0000000..836594d
--- /dev/null
+++ b/tests/features/test_concurrency_suite.zc
@@ -0,0 +1,98 @@
+//> link: -lpthread
+import "std/thread.zc"
+
+async fn double_slowly(x: int) -> int {
+ usleep(1000);
+ return x * 2;
+}
+
+async fn add_async(a: int, b: int) -> int {
+ return a + b;
+}
+
+async fn say_hello() {
+ puts("Hello from async!");
+}
+
+struct Point {
+ x: int;
+ y: int;
+}
+
+async fn make_point(x: int, y: int) -> Point {
+ return Point{x: x, y: y};
+}
+
+struct Counter {
+ val: int;
+ lock: Mutex;
+}
+
+test "test_async_basics" {
+ var future1 = double_slowly(21);
+ var future2 = add_async(10, 20);
+
+ var result1 = await future1;
+ var result2 = await future2;
+
+ assert(result1 == 42, "Async double failed");
+ assert(result2 == 30, "Async add failed");
+}
+
+test "test_async_struct_return" {
+ var f = make_point(5, 7);
+ var p = await f;
+
+ assert(p.x == 5, "Async struct x failed");
+ assert(p.y == 7, "Async struct y failed");
+}
+
+test "test_async_void" {
+ var f = say_hello();
+ await f;
+}
+
+test "test_thread" {
+ println "Testing Concurrency...";
+
+ var c = (Counter*)malloc(sizeof(Counter));
+ c.val = 0;
+ c.lock = Mutex::new();
+
+ const N = 10000;
+
+ var t1_res = Thread::spawn(fn() {
+ for (var i=0; i<N; ++i) {
+ c.lock.lock();
+ c.val = c.val + 1;
+ c.lock.unlock();
+ }
+ });
+
+ var t2_res = Thread::spawn(fn() {
+ for (var i=0; i<N; ++i) {
+ c.lock.lock();
+ c.val = c.val + 1;
+ c.lock.unlock();
+ }
+ });
+
+ assert(t1_res.is_err() == false, "T1 failed to spawn");
+ assert(t2_res.is_err() == false, "T2 failed to spawn");
+
+ var t1 = t1_res.unwrap();
+ var t2 = t2_res.unwrap();
+
+ t1.join();
+ t2.join();
+
+ println "Final Count: {c.val} (Expected {2 * N})";
+
+ var final_val = c.val;
+
+ c.lock.free();
+ free(c);
+
+ assert(final_val == 2 * N, "Concurrency count mismatch");
+ println "Concurrency Test Passed!";
+}