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
|
extern crate psm;
psm::psm_stack_manipulation! {
yes {
use std::alloc;
const STACK_ALIGN: usize = 4096;
const FRAME_SIZE: usize = 4096;
const FIB_COUNTS: [(usize, u64); 3] = [
(8, 21),
(16, 987),
(24, 46368),
];
#[inline(never)]
fn fib(n: usize) -> u64 {
unsafe {
let layout = alloc::Layout::from_size_align(FRAME_SIZE, STACK_ALIGN).unwrap();
let new_stack = alloc::alloc(layout);
assert!(!new_stack.is_null(), "allocations must succeed!");
let r = match n {
0 => 0,
1 => 1,
_ => {
psm::on_stack(new_stack, FRAME_SIZE, || {
fib(n - 1) + fib(n - 2)
})
}
};
alloc::dealloc(new_stack, layout);
r
}
}
fn main() {
for (n, expected, handle) in FIB_COUNTS.iter().map(|&(n, expected)|
(n, expected, std::thread::spawn(move || {
fib(n)
}))
) {
if let Ok(res) = handle.join() {
assert_eq!(res, expected);
println!("fib({}) = {}", n, res);
} else {
panic!("joining a thread returned an Err");
}
}
}
}
no {
fn main() {
eprintln!("Stack manipulation not supported by this target");
}
}
}
#[test]
fn run_example() {
main()
}
|