Concurrency =========== BearVM provides two instructions for task-based concurrency: ``spawn`` and ``sync``. Model ----- Each ``spawn`` launches a new OS thread via Zig's ``std.Thread`` API. The spawned thread runs the specified function with the given arguments independently of the caller. ``sync`` blocks the calling thread until the spawned thread completes and returns its result. This is straightforward OS-thread parallelism. There is no thread pool, no work-stealing scheduler, and no green thread runtime. Spawning a Task --------------- ``spawn call ()`` starts a new thread and returns a task handle:: %task1 = spawn call fib(%n1) %task2 = spawn call fib(%n2) Both calls return immediately. The two ``fib`` invocations run concurrently. Synchronising ------------- ``sync `` blocks until the task finishes and returns its result:: %r1 = sync %task1 %r2 = sync %task2 %res = add %r1, %r2 ret %res ``sync`` must be called for every spawned task. If a task fails, ``sync`` propagates the error. Full Example ------------ The following computes Fibonacci recursively with each pair of sub-problems running in parallel:: @fib(%n: int): int { entry: %cond0 = le %n, 1 br_if %cond0, base_case, recursive_case base_case: ret %n recursive_case: %n1 = sub %n, 1 %n2 = sub %n, 2 %task1 = spawn call fib(%n1) %task2 = spawn call fib(%n2) %r1 = sync %task1 %r2 = sync %task2 %res = add %r1, %r2 ret %res } @main(): int { entry: %n = const 10 %task_fib = spawn call fib(%n) %result = sync %task_fib %task_print = spawn call puts(%result) %r = sync %task_print ret 0 } Notes ----- - Each ``spawn`` creates a real OS thread. Spawning a large number of threads simultaneously will behave as the underlying OS dictates. - There is no built-in mechanism for shared mutable state or synchronisation primitives beyond ``spawn`` and ``sync``.