Landin library reference discuss source

compiler/tests/fixtures/runtime/fibre-turns-interleave/main.ldn

1--  D444: a group over a round of turns runs two tasks that yield in turn,
2--  each letting the other run before it resumes, so their letters
3--  interleave.  The round's home stack makes the group and goes on past
4--  both admissions before either task has run, and its join takes turns
5--  until both have ended.
6import core/failure
7import core/fibre
8import core/fibre/stacks
9import core/io
10import hosted/system
11
12mut order: [16]u8 = zeroed
13mut steps: usize = 0
14
15note: type = struct
16    runs: any fibre.turns
17    letter: u8
18end note
19
20note_of: (runs: any fibre.turns, letter: u8) -> (made: note from runs) =
21    made = (runs: runs, letter: letter)
22end note_of
23
24mark: (letter: u8) -> none =
25    order[steps] = letter
26    steps += 1
27end mark
28
29--  Three letters, with a turn after each of the first two.
30thrice: (inout state: note) -> none ! failure.reason =
31    mark(state.letter)
32    state.runs.yield()
33    mark(state.letter)
34    state.runs.yield()
35    mark(state.letter)
36end thrice
37
38both: (runs: any fibre.turns) -> none ! failure.reason =
39    mut stacks: [2 * 8192]u8 = zeroed
40    mut tasks := try fibre.turns_over(runs, stacks, 2)
41    defer fibre.join(tasks) else none
42    a := note_of(runs, u8('a'))
43    try fibre.admit(tasks, thrice, a)
44    b := note_of(runs, u8('b'))
45    try fibre.admit(tasks, thrice, b)
46    mark(u8('h'))
47    try fibre.join(tasks)
48    mark(u8('j'))
49end both
50
51public main: () -> (code: i32) =
52    code = 1
53    host := system.new()
54    mut state: stacks.round_space = zeroed
55    mut entries: [3]usize = zeroed
56    idler: stacks.spin = zeroed
57    round := stacks.round_over(state, entries, any(addr idler)) else (problem)
58        _ = problem
59        return
60    end
61    both(any(addr round)) else (problem)
62        _ = problem
63        return
64    end
65    mut storage: [64]u8 = zeroed
66    mut out := io.buffered_over(host, io.out(host), storage)
67    io.put(out, order[0..<steps]) else none
68    io.put(out, "\n") else none
69    io.flush(out) else none
70    code = 0
71end main