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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::time::{Duration, Instant};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    global()?;
    local()?;
    Ok(())
}

#[inline(never)]
fn global() -> Result<(), Box<dyn std::error::Error>> {
    tasc::blocking::task(|_id| {}).wait()?;

    let mut x = vec![0; 200];
    let (a, b) = x.split_at_mut(2);
    let (c, d) = b.split_at_mut(5);
    let task0 = tasc::blocking::scoped(|_id| {
        for e in a {
            *e += 1;
        }
    });
    let task1 = tasc::blocking::scoped(|_id| {
        for e in c {
            *e += 1;
        }
        for e in d {
            *e += 1;
        }
    });

    task0.wait()?;
    task1.wait()?;

    assert_eq!(x.iter().sum::<u32>(), 200);

    #[inline(never)]
    fn sum(start: u64, end: u64) -> u64 {
        let mut sum = 0;
        for v in start..end {
            sum = std::hint::black_box(sum + v);
        }
        sum
    }

    println!("summing large numbers");
    let n0 = 10_000_000_000;
    let n1 = 20_000_000_000;
    let n2 = 30_000_000_000;
    let sum_0_to_n0 = tasc::blocking::task(move |_| {
        let start = Instant::now();
        let res = sum(0, n0);
        println!(
            "summed 0 - {n0}, time: {:.02}",
            (Instant::now() - start).as_secs_f64()
        );
        res
    });
    let sum_0_to_n1 = tasc::blocking::task(move |_| {
        let start = Instant::now();
        let res = sum(0, n1);
        println!(
            "summed 0 - {n1}, time: {:.02}",
            (Instant::now() - start).as_secs_f64()
        );
        res
    });
    let sum_0_to_n2 = tasc::blocking::task(move |_| {
        let start = Instant::now();
        let res = sum(0, n2);
        println!(
            "summed 0 - {n2}, time: {:.02}",
            (Instant::now() - start).as_secs_f64()
        );
        res
    });
    let sum: tasc::error::Result<u64> = *tasc::blocking::task(|_| {
        Ok(*sum_0_to_n2.wait()? + *sum_0_to_n1.wait()? + *sum_0_to_n0.wait()?)
    })
    .wait()?;
    let sum = sum?;
    println!("sum: {sum}");
    assert_eq!(
        sum,
        (0..n0).sum::<u64>() + (0..n1).sum::<u64>() + (0..n2).sum::<u64>()
    );

    Ok(())
}

#[inline(never)]
fn local() -> Result<(), Box<dyn std::error::Error>> {
    type TaskBuilder<'a> = tasc::TaskBuilder<'a, tasc::StdContext, tasc::StdSignal>;

    let ctx = tasc::StdContext::new_blocking(100);
    let task0 = TaskBuilder::from_ctx(&ctx).spawn_blocking(|_id| {
        println!("task0");
        std::thread::sleep(Duration::from_secs(3));
        let mut i = 0u128;
        #[allow(clippy::unit_arg)]
        std::hint::black_box(for _ in 0..100000 {
            i += 1;
        });
        println!("task 0 finished");
        i
    });
    let task1 = TaskBuilder::from_ctx(&ctx).spawn_blocking(|_id| {
        println!("task1");
        let mut i = 0u128;
        #[allow(clippy::unit_arg)]
        std::hint::black_box(for _ in 0..100000 {
            i += 1;
        });
        println!("task 1 finished");
        i
    });
    let task2 = TaskBuilder::from_ctx(&ctx).spawn_blocking(|_id| {
        println!("task2");
        let mut i = 0u128;
        #[allow(clippy::unit_arg)]
        std::hint::black_box(for _ in 0..100000 {
            i += 1;
        });
        println!("task 2 finished");
        i
    });

    println!("task0: {}", task0.wait()?);
    println!("task1: {}", task1.wait()?);
    println!("task2: {}", task2.wait()?);
    Ok(())
}