1 // run-pass
2 #![allow(unused_must_use)]
3 // This time we're testing repeatedly going up and down both stacks to
4 // make sure the stack pointers are maintained properly in both
5 // directions
6 
7 // ignore-emscripten no threads support
8 #![feature(rustc_private)]
9 
10 extern crate libc;
11 use std::thread;
12 
13 mod rustrt {
14     extern crate libc;
15 
16     #[link(name = "rust_test_helpers", kind = "static")]
17     extern "C" {
rust_dbg_call( cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, data: libc::uintptr_t, ) -> libc::uintptr_t18         pub fn rust_dbg_call(
19             cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
20             data: libc::uintptr_t,
21         ) -> libc::uintptr_t;
22     }
23 }
24 
cb(data: libc::uintptr_t) -> libc::uintptr_t25 extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
26     if data == 1 { data } else { count(data - 1) + count(data - 1) }
27 }
28 
count(n: libc::uintptr_t) -> libc::uintptr_t29 fn count(n: libc::uintptr_t) -> libc::uintptr_t {
30     unsafe {
31         println!("n = {}", n);
32         rustrt::rust_dbg_call(cb, n)
33     }
34 }
35 
main()36 pub fn main() {
37     // Make sure we're on a thread with small Rust stacks (main currently
38     // has a large stack)
39     thread::spawn(move || {
40         let result = count(12);
41         println!("result = {}", result);
42         assert_eq!(result, 2048);
43     })
44     .join();
45 }
46