@@ -3,22 +3,27 @@ use core::sync::atomic::{AtomicBool, Ordering};
33use core:: time:: Duration ;
44
55use anstyle:: AnsiColor ;
6+ use hermit_sync:: OnceCell ;
67use log:: { Level , LevelFilter , Metadata , Record } ;
78
89pub static KERNEL_LOGGER : KernelLogger = KernelLogger :: new ( ) ;
10+ const ARENA_SIZE : usize = 4096 ;
11+ static mut ARENA : [ u8 ; ARENA_SIZE ] = [ 0 ; _] ;
912
1013const TIME_SEC_WIDTH : usize = 5 ;
1114const TIME_SUBSEC_WIDTH : usize = 6 ;
1215
1316/// Data structure to filter kernel messages
1417pub struct KernelLogger {
1518 time : AtomicBool ,
19+ filter : OnceCell < env_filter:: Filter > ,
1620}
1721
1822impl KernelLogger {
1923 pub const fn new ( ) -> Self {
2024 Self {
2125 time : AtomicBool :: new ( false ) ,
26+ filter : OnceCell :: new ( ) ,
2227 }
2328 }
2429
@@ -45,6 +50,12 @@ impl log::Log for KernelLogger {
4550 return ;
4651 }
4752
53+ if let Some ( filter) = self . filter . get ( )
54+ && !filter. matches ( record)
55+ {
56+ return ;
57+ }
58+
4859 let format_time = if self . time ( ) {
4960 let time = Duration :: from_micros ( crate :: processor:: get_timer_ticks ( ) ) ;
5061 format_args ! (
@@ -101,29 +112,29 @@ fn no_color() -> bool {
101112}
102113
103114pub unsafe fn init ( ) {
115+ #[ cfg( target_os = "none" ) ]
116+ unsafe {
117+ crate :: mm:: ALLOCATOR
118+ . lock ( )
119+ . claim ( ( & raw mut ARENA ) . cast ( ) , ARENA_SIZE )
120+ . unwrap ( )
121+ } ;
122+
104123 log:: set_logger ( & KERNEL_LOGGER ) . expect ( "Can't initialize logger" ) ;
105124 // Determines LevelFilter at compile time
106125 let log_level: Option < & ' static str > = option_env ! ( "HERMIT_LOG_LEVEL_FILTER" ) ;
107- let mut max_level = LevelFilter :: Info ;
108-
109- if let Some ( log_level) = log_level {
110- max_level = if log_level. eq_ignore_ascii_case ( "off" ) {
111- LevelFilter :: Off
112- } else if log_level. eq_ignore_ascii_case ( "error" ) {
113- LevelFilter :: Error
114- } else if log_level. eq_ignore_ascii_case ( "warn" ) {
115- LevelFilter :: Warn
116- } else if log_level. eq_ignore_ascii_case ( "info" ) {
117- LevelFilter :: Info
118- } else if log_level. eq_ignore_ascii_case ( "debug" ) {
119- LevelFilter :: Debug
120- } else if log_level. eq_ignore_ascii_case ( "trace" ) {
121- LevelFilter :: Trace
122- } else {
123- error ! ( "Could not parse HERMIT_LOG_LEVEL_FILTER, falling back to `info`." ) ;
124- LevelFilter :: Info
125- } ;
126- }
126+ let max_level = if let Some ( log_level) = log_level {
127+ let filter = env_filter:: Builder :: new ( )
128+ // The default. It may get overwritten by the parsed filter if it has a global level.
129+ . filter_level ( LevelFilter :: Info )
130+ . parse ( log_level)
131+ . build ( ) ;
132+ let max_level = filter. filter ( ) ;
133+ KERNEL_LOGGER . filter . set ( filter) . unwrap ( ) ;
134+ max_level
135+ } else {
136+ LevelFilter :: Info
137+ } ;
127138
128139 log:: set_max_level ( max_level) ;
129140}
0 commit comments