summary refs log tree commit diff
path: root/src/test/bench/shootout-threadring.rs
blob: 42a17b8d4812fb361187569bcb77dbb50a4193f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Based on threadring.erlang by Jira Isa
use std;

const n_threads: int = 503;

fn start(+token: int) {
    import iter::*;

    let p = comm::port();
    let ch = iter::foldl(bind int::range(2, n_threads + 1, _),
                         comm::chan(p)) { |ch, i|
        let id = n_threads + 2 - i;
        let to_child = task::spawn_listener::<int> {|p|
            roundtrip(id, p, ch)
        };
        to_child
    };
    comm::send(ch, token);
    roundtrip(1, p, ch);
}

fn roundtrip(id: int, p: comm::port<int>, ch: comm::chan<int>) {
    while (true) {
        alt comm::recv(p) {
          1 {
            io::println(#fmt("%d\n", id));
            ret;
          }
          token {
            #debug("%d %d", id, token);
            comm::send(ch, token - 1);
            if token <= n_threads {
                ret;
            }
          }
        }
    }
}

fn main(args: [str]) {
    let token = if vec::len(args) < 2u { 1000 }
                else { option::get(int::from_str(args[1])) };

    start(token);
}