#!/usr/bin/env bx use stdio.h use sched use shuttle use error use util main() sched_init() new(c3, count_to_three) new(pr, printer) shuttle(sh, int, c3, out, pr, in) new(pd, print_dots, 20) start(c3) ; start(pr) ; start(pd) ; run() new(cn, count_to_n, 7) new(cn2, count_to_n_passive, 19) new(pr2, printer_controlling) shuttle(sh1, int, cn, out, pr, in) shuttle(sh2, int, cn2, out, pr2, in) start(cn) ; start(pr) ; start(cn2) ; start(pr2) ; run() # this is the "passive writer" technique process count_to_three() port int out wr(out, 1) wr(out, 2) wr(out, 3) # this shows the "passive reader" technique process printer() port int in repeat int v rd(in, v) printf("%d\n", v) # this shows the "controlling reader" technique # "controlling" processes are to be avoided if there is a simple passive impl, # because they limit concurrency process printer_controlling() port int in pull(in) repeat printf("%d\n", d(in)) next(in) # this is the "passive writer" technique again # also shows how to declare additional state variables (apart from the ports and arguments) process count_to_n_passive(int n) port int out state int i for i=1 ; i<=n ; ++i wr(out, i) # this is the "controlling writer" technique # this is a good way to do this one without using an extra temporary variable # TODO maybe: make d(out) accessible via just "out" and change pull, push, next # etc to find the shuttle address from the data address # would have to do this partly in brace_process ?? # the pointer arithmetic sounds ugly, but theoretically the optimiser would get rid of it... # could do it without bullshit pointer arithmetic if pull, push, next are # builtins implemented in brace_process - would need to split lines on `;' first process count_to_n(int n) port int out pull(out) for d(out)=1 ; d(out)<=n ; ++d(out) next(out) # this one is an example of normal yielding process print_dots(int n) while n > 0 printf(".\n") -- n yield # TODO include this shuttle struct automatically, and change # brace_shuffle to remove redundant identical definitions. shuttle(int)