| 1 | // Default allocator: mimalloc. `--no-default-features --features rusty-alloc` |
| 2 | // selects the Rust allocator without building the C allocator (#5872). |
| 3 | // With neither feature the standard library system allocator is used. |
| 4 | #[cfg(all(feature = "mimalloc-allocator", not(feature = "rusty-alloc")))] |
| 5 | #[global_allocator] |
| 6 | static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; |
| 7 | |
| 8 | // mimalloc tags its macOS VM regions with tag 100 by default, which macOS |
| 9 | // names `VM_MEMORY_IOACCELERATOR`. `footprint`, `vmmap` and Activity Monitor |
| 10 | // then report the whole heap as GPU memory ("61 MB IOAccelerator" at idle), |
| 11 | // which reads as AppKit/CoreAnimation initialising when nothing GPU-related |
| 12 | // runs. Retag to 254 (VM_MEMORY_APPLICATION_SPECIFIC_15) so the heap is |
| 13 | // labelled as the app's own memory. This must run before the first |
| 14 | // allocation, because the tag sticks to the arena mimalloc reserves then; |
| 15 | // setting it from `main` is already too late, so it runs as a Mach-O |
| 16 | // initializer. An explicit `MIMALLOC_OS_TAG` still wins. |
| 17 | #[cfg(all( |
| 18 | target_os = "macos", |
| 19 | feature = "mimalloc-allocator", |
| 20 | not(feature = "rusty-alloc") |
| 21 | ))] |
| 22 | #[used] |
| 23 | #[unsafe(link_section = "__DATA,__mod_init_func")] |
| 24 | static MIMALLOC_RETAG: extern "C" fn() = { |
| 25 | extern "C" fn retag_mimalloc_heap() { |
| 26 | unsafe extern "C" { |
| 27 | fn mi_option_set(option: std::ffi::c_int, value: std::ffi::c_long); |
| 28 | } |
| 29 | /// `mi_option_os_tag` in mimalloc's `mi_option_e`. |
| 30 | const MI_OPTION_OS_TAG: std::ffi::c_int = 18; |
| 31 | if std::env::var_os("MIMALLOC_OS_TAG").is_none() { |
| 32 | // SAFETY: mimalloc's option setter is callable before its own |
| 33 | // initialisation; it only stores the value. |
| 34 | unsafe { mi_option_set(MI_OPTION_OS_TAG, 254) }; |
| 35 | } |
| 36 | } |
| 37 | retag_mimalloc_heap |
| 38 | }; |
| 39 | |
| 40 | #[cfg(feature = "rusty-alloc")] |
| 41 | #[global_allocator] |
| 42 | static GLOBAL: rusty_alloc_api::RustyAlloc = rusty_alloc_api::RustyAlloc; |
| 43 | |
| 44 | fn main() -> std::process::ExitCode { |
| 45 | // Reset SIGPIPE to SIG_DFL so piping codewhale output into a command that |
| 46 | // exits early (e.g. `codewhale doctor | head`) terminates the process |
| 47 | // cleanly with exit code 141 instead of panicking on the broken-pipe |
| 48 | // write. Many execution environments (systemd, Docker, some shells) |
| 49 | // inherit SIGPIPE set to SIG_IGN, which makes write(2) return EPIPE; |
| 50 | // Rust's `println!` then treats that io::Error as fatal and panics. |
| 51 | // See issue #4030. |
| 52 | // SAFETY: process entry; no threads or handlers yet. |
| 53 | #[cfg(unix)] |
| 54 | unsafe { |
| 55 | libc::signal(libc::SIGPIPE, libc::SIG_DFL); |
| 56 | } |
| 57 | |
| 58 | // Published codew/codewhale-tui compatibility names are copies or links |
| 59 | // to this executable and use the same CLI parser and Engine entrypoint. |
| 60 | codewhale_cli::run_cli() |
| 61 | } |
| 62 |