Concurrency

START / WAIT

START/WAIT starts a thread running in a routine and waits (joins) at thread termination. Unlike COEND, it allows arbitrary thread graphs — start and wait are not paired in a syntactic block.

When do I need this over COBEGIN/COEND?

When your dependency shape isn’t a tree. Imagine: start p, then do work, start f, do more work, wait for p, do more, wait for f. The wait points interleave with sequential code in a way COBEGIN/COEND can’t express without contorting the nesting. START/WAIT gives you the fork/join as two separate primitives that you place independently.

uC++ form

#include <uCobegin.h>
int i;
void p( int i ) { ... }
int f( int i ) { ... }
auto tp = START( p, 5 );    // fork
s1          // continue execution — do not wait for p
auto tf = START( f, 8 );    // fork
s2
WAIT( tp );                  // join p
s3
i = WAIT( tf );              // join f — and capture return value
s4

Symmetry with COBEGIN/COEND

COBEGIN/COEND can be simulated by START/WAIT:

auto t1 = START( p1, ... );
auto t2 = START( p2, ... );
WAIT t1;  WAIT t2;

But the reverse isn’t true — a thread graph with interleaved starts and waits approximates poorly in COBEGIN/COEND nesting.