gear_dlmalloc/
dlverbose.rs

1use core::fmt::Arguments;
2
3pub static DL_DEBUG: bool = cfg!(feature = "debug");
4pub static DL_CHECKS: bool = cfg!(feature = "checks");
5pub static DL_VERBOSE: bool = cfg!(feature = "verbose");
6pub static VERBOSE_DEL: &str = "====================================";
7
8#[cfg(unix)]
9mod ext {
10    pub fn debug(s: &str, _size: usize) {
11        libc_print::libc_println!("{}", s);
12    }
13}
14
15#[cfg(windows)]
16mod ext {
17    pub fn debug(_s: &str, _size: usize) {
18        unreachable!("Windows is unsupported");
19    }
20}
21
22#[cfg(target_arch = "wasm32")]
23mod ext {
24    mod sys {
25        extern "C" {
26            pub fn gr_debug(msg_ptr: *const u8, msg_len: u32);
27        }
28    }
29    pub fn debug(s: &str, size: usize) {
30        unsafe { sys::gr_debug(s.as_ptr(), size as _) }
31    }
32}
33
34/// Static out buffer type
35type StaticStr = str_buf::StrBuf<200>;
36/// Static out buffer - we use it to avoid memory allocations,
37/// when something is printed inside allocator code.
38static mut OUT_BUFFER: StaticStr = StaticStr::new();
39
40/// Prints string with args.
41/// What is the out stream defines in @ext module.
42#[inline(never)]
43pub fn dlprint_fn(args: Arguments<'_>) {
44    unsafe {
45        core::fmt::write(&mut OUT_BUFFER, args).unwrap();
46        ext::debug(&OUT_BUFFER, OUT_BUFFER.len());
47        OUT_BUFFER.set_len(0);
48    }
49}
50
51/// Prints string with args.
52/// What is the out stream defines in @ext module.
53#[inline(never)]
54pub fn dlwrite_fn(args: Arguments<'_>) {
55    unsafe {
56        core::fmt::write(&mut OUT_BUFFER, args).unwrap();
57    }
58}
59
60/// Prints string with args if @DL_VERBOSE is set.
61/// What is the out stream defines in @ext module.
62#[macro_export]
63macro_rules! dlverbose {
64    ($($arg:tt)*) => {
65        if crate::dlverbose::DL_VERBOSE {
66            crate::dlverbose::dlprint_fn(format_args!($($arg)*))
67        }
68    }
69}
70
71/// Prints string with args if @DL_VERBOSE is set.
72/// What is the out stream defines in @ext module.
73#[macro_export]
74macro_rules! dlverbose_no_flush {
75    ($($arg:tt)*) => {
76        if crate::dlverbose::DL_VERBOSE {
77            crate::dlverbose::dlwrite_fn(format_args!($($arg)*))
78        }
79    }
80}
81
82extern crate alloc;
83use self::alloc::alloc::handle_alloc_error;
84
85/// Prints current line and throw error using @handle_alloc_error.
86#[inline(never)]
87pub fn dlassert_fn(line: u32) {
88    dlprint_fn(format_args!("ALLOC ASSERT: {}", line));
89    handle_alloc_error(self::alloc::alloc::Layout::new::<u32>());
90}
91
92/// Acts like assert using handle_alloc_error if @DL_CHECKS is set, else does nothing.
93#[macro_export]
94macro_rules! dlassert {
95    ($check:expr) => {
96        if crate::dlverbose::DL_DEBUG && !($check) {
97            crate::dlverbose::dlassert_fn(line!());
98        }
99    };
100}