Skip to main content

thread/
thread.rs

1extern crate psm;
2
3psm::psm_stack_manipulation! {
4    yes {
5        use std::alloc;
6
7        const STACK_ALIGN: usize = 4096;
8        const FRAME_SIZE: usize = 4096;
9        const FIB_COUNTS: [(usize, u64); 3] = [
10            (8, 21),
11            (16, 987),
12            (24, 46368),
13        ];
14
15        #[inline(never)]
16        fn fib(n: usize) -> u64 {
17            unsafe {
18                let layout = alloc::Layout::from_size_align(FRAME_SIZE, STACK_ALIGN).unwrap();
19                let new_stack = alloc::alloc(layout);
20                assert!(!new_stack.is_null(), "allocations must succeed!");
21                let r = match n {
22                    0 => 0,
23                    1 => 1,
24                    _ => {
25                        psm::on_stack(new_stack, FRAME_SIZE, || {
26                            fib(n - 1) + fib(n - 2)
27                        })
28                    }
29                };
30                alloc::dealloc(new_stack, layout);
31                r
32            }
33        }
34
35        fn main() {
36            for (n, expected, handle) in FIB_COUNTS.iter().map(|&(n, expected)|
37                (n, expected, std::thread::spawn(move || {
38                    fib(n)
39                }))
40            ) {
41                if let Ok(res) = handle.join() {
42                    assert_eq!(res, expected);
43                    println!("fib({}) = {}", n, res);
44                } else {
45                    panic!("joining a thread returned an Err");
46                }
47            }
48        }
49    }
50    no {
51        fn main() {
52            eprintln!("Stack manipulation not supported by this target");
53        }
54    }
55}
56
57#[test]
58fn run_example() {
59    main()
60}