1 #![deny(unsafe_op_in_unsafe_fn)]
2 #![allow(unused_macros)]
6 use crate::sys_common::thread_info;
7 use crate::thread::Thread;
9 // One-time runtime initialization.
10 // Runs before `main`.
11 // SAFETY: must be called only once during runtime initialization.
12 // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
13 #[cfg_attr(test, allow(dead_code))]
14 pub unsafe fn init(argc: isize, argv: *const *const u8) {
16 sys::init(argc, argv);
18 let main_guard = sys::thread::guard::init();
19 // Next, set up the current Thread with the guard information we just
20 // created. Note that this isn't necessary in general for new threads,
21 // but we just do this to name the main thread and to give it correct
22 // info about the stack bounds.
23 let thread = Thread::new(Some("main".to_owned()));
24 thread_info::set(main_guard, thread);
28 // One-time runtime cleanup.
29 // Runs after `main` or at program exit.
30 // NOTE: this is not guaranteed to run, for example when the program aborts.
31 #[cfg_attr(test, allow(dead_code))]
33 static CLEANUP: Once = Once::new();
34 CLEANUP.call_once(|| unsafe {
35 // Flush stdout and disable buffering.
37 // SAFETY: Only called once during runtime cleanup.
44 if let Some(mut out) = crate::sys::stdio::panic_output() {
45 let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
50 macro_rules! rtabort {
53 rterr!("fatal runtime error: {}\n", format_args!($($t)*));
54 crate::sys::abort_internal();
59 macro_rules! rtassert {
62 rtabort!(concat!("assertion failed: ", stringify!($e)));
67 macro_rules! rtunwrap {
68 ($ok:ident, $e:expr) => {
72 let err = err.as_ref().map(drop); // map Ok/Some which might not be Debug
73 rtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err)