1use core::fmt::{self, Write};
2use core::panic::PanicInfo;
3use core::sync::atomic::{AtomicBool, Ordering};
4
5use crate::console;
6use crate::proc::Cpus;
7use crate::spinlock::Mutex;
8
9pub static PRINTF: Printf = Printf {
10 writer: Mutex::new(Writer, "printf"),
11 locking: AtomicBool::new(true),
12 panicked: AtomicBool::new(false),
13};
14
15pub struct Printf {
16 writer: Mutex<Writer>,
17 locking: AtomicBool,
18 panicked: AtomicBool,
19}
20
21impl Printf {
22 pub fn is_panicked(&self) -> &AtomicBool {
23 &self.panicked
24 }
25}
26
27pub struct Writer;
28
29impl Writer {
30 fn print(&self, c: u8) {
31 console::putc(c)
32 }
33}
34
35impl fmt::Write for Writer {
36 fn write_str(&mut self, s: &str) -> fmt::Result {
37 for byte in s.bytes() {
38 self.print(byte);
39 }
40 Ok(())
41 }
42}
43
44pub fn _print(args: fmt::Arguments<'_>, newline: bool) {
45 if PRINTF.locking.load(Ordering::Relaxed) {
46 let mut lock = PRINTF.writer.lock();
47 lock.write_fmt(args).unwrap();
48 if newline {
49 lock.write_char('\n');
50 }
51 } else {
52 unsafe {
54 let writer = PRINTF.writer.get_mut_unchecked();
55 writer.write_fmt(args).unwrap();
56 if newline {
57 writer.write_char('\n');
58 }
59 }
60 }
61}
62
63#[macro_export]
64macro_rules! print {
65 ($($arg:tt)*) => {{
66 $crate::printf::_print(format_args!($($arg)*), false);
67 }};
68}
69
70#[macro_export]
71macro_rules! println {
72 () => {
73 $crate::print!("\n");
74 };
75 ($($arg:tt)*) => {{
76 $crate::printf::_print(format_args!($($arg)*), true);
77 }};
78}
79
80static mut EWRITER: Writer = Writer;
81
82pub fn _eprint(args: fmt::Arguments<'_>) {
83 unsafe {
84 EWRITER.write_fmt(args).unwrap();
85 }
86}
87
88#[macro_export]
89macro_rules! eprint {
90 ($($arg:tt)*) => {{
91 $crate::printf::_eprint(format_args!($($arg)*));
92 }};
93}
94
95pub fn handle_panic(info: &PanicInfo) -> ! {
96 PRINTF.locking.store(false, Ordering::Relaxed);
97
98 let cpu_id = unsafe { Cpus::get_id() };
99 eprint!("hart {cpu_id} panicked: {info}\n");
100
101 PRINTF.panicked.store(false, Ordering::Relaxed);
102
103 loop {}
104}