@@ -7,10 +7,13 @@ use core::future::{poll_fn, Future};
77use core:: pin:: Pin ;
88use core:: sync:: atomic:: { AtomicBool , AtomicU64 , Ordering } ;
99use core:: task:: { Context , Poll , Waker } ;
10+
1011use spin:: Mutex ;
1112use uefi:: boot:: { EventType , TimerTrigger , Tpl } ;
13+ use uefi:: proto:: console:: text:: Color ;
1214
1315use crate :: os:: timer:: Timer ;
16+ use crate :: os:: ui:: DrawArea ;
1417
1518struct BoxFuture ( Pin < Box < dyn Future < Output = ( ) > + ' static > > ) ;
1619
@@ -22,6 +25,7 @@ struct Task {
2225 in_queue : AtomicBool ,
2326 future : Mutex < BoxFuture > ,
2427 micros : AtomicU64 ,
28+ last_micros : AtomicU64 ,
2529}
2630
2731impl Task {
@@ -33,6 +37,7 @@ impl Task {
3337 name,
3438 future : Mutex :: new ( BoxFuture ( Box :: pin ( future) ) ) ,
3539 micros : AtomicU64 :: new ( 0 ) ,
40+ last_micros : AtomicU64 :: new ( 0 ) ,
3641 in_queue : AtomicBool :: new ( false ) ,
3742 } )
3843 }
@@ -58,7 +63,99 @@ pub struct Executor {
5863}
5964
6065impl Executor {
66+ async fn draw_tasks ( ) {
67+ let mut draw_area = DrawArea :: tasks ( ) ;
68+ let ( w, h) = draw_area. size ( ) ;
69+ const TASK_LEN : usize = 34 ;
70+ let num_w = ( w - 2 ) / TASK_LEN ;
71+ let total_w = num_w * TASK_LEN + 2 ;
72+ let pad = ( w - total_w) / 2 ;
73+ let mut last = Timer :: micros ( ) as u64 ;
74+ Self :: sleep_us ( 100_000 ) . await ;
75+ loop {
76+ draw_area. clear ( ) ;
77+ let cur = Timer :: micros ( ) as u64 ;
78+ let elapsed = cur. saturating_sub ( last) . max ( 1 ) as f64 ;
79+ {
80+ let mut executor = EXECUTOR . lock ( ) ;
81+ let tasks = & mut executor. tasks ;
82+ // Sort by *descending* time used since last draw.
83+ tasks. sort_unstable_by_key ( |f| {
84+ f. last_micros . load ( Ordering :: Relaxed ) as i64
85+ - f. micros . load ( Ordering :: Relaxed ) as i64
86+ } ) ;
87+
88+ draw_area. advance ( pad) ;
89+ draw_area. write ( "\u{250C} " ) ;
90+ for x in 0 ..num_w {
91+ for _ in 0 ..TASK_LEN {
92+ draw_area. write ( "\u{2500} " ) ;
93+ }
94+ draw_area. write ( if x + 1 == num_w {
95+ "\u{2510} "
96+ } else {
97+ "\u{252C} "
98+ } ) ;
99+ }
100+ draw_area. newline ( ) ;
101+ for y in 0 ..( h - 2 ) {
102+ draw_area. advance ( pad) ;
103+ draw_area. write ( "\u{2502} " ) ;
104+ for x in 0 ..num_w {
105+ let idx = x * h + y;
106+ if idx >= tasks. len ( ) {
107+ draw_area. advance ( TASK_LEN ) ;
108+ } else {
109+ let task = & tasks[ idx] ;
110+ let total_cpu = task. micros . load ( Ordering :: Relaxed ) ;
111+ let last_cpu = task. last_micros . load ( Ordering :: Relaxed ) ;
112+ let frac = ( ( total_cpu - last_cpu) as f64 / elapsed) . min ( 1.0 ) ;
113+ draw_area. write_with_color (
114+ & format ! (
115+ " {:15}{:5.1}%{:10.3}s " ,
116+ & task. name[ ..task. name. len( ) . min( 15 ) ] ,
117+ frac * 100.0 ,
118+ total_cpu as f64 * 0.000_001 ,
119+ ) ,
120+ if frac >= 0.5 {
121+ Color :: Red
122+ } else if frac >= 0.1 {
123+ Color :: Yellow
124+ } else {
125+ Color :: White
126+ } ,
127+ Color :: Black ,
128+ ) ;
129+ }
130+ draw_area. write ( "\u{2502} " ) ;
131+ }
132+ draw_area. newline ( ) ;
133+ }
134+ draw_area. advance ( pad) ;
135+ draw_area. write ( "\u{2514} " ) ;
136+ for x in 0 ..num_w {
137+ for _ in 0 ..TASK_LEN {
138+ draw_area. write ( "\u{2500} " ) ;
139+ }
140+ draw_area. write ( if x + 1 == num_w {
141+ "\u{2518} "
142+ } else {
143+ "\u{2534} "
144+ } ) ;
145+ }
146+
147+ for t in tasks. iter ( ) {
148+ t. last_micros
149+ . store ( t. micros . load ( Ordering :: Relaxed ) , Ordering :: Relaxed ) ;
150+ }
151+ }
152+ last = Timer :: micros ( ) as u64 ;
153+ Self :: sleep_us ( 1_000_000 ) . await ;
154+ }
155+ }
156+
61157 pub fn run ( ) -> ! {
158+ Self :: spawn ( "[show_tasks]" , Self :: draw_tasks ( ) ) ;
62159 loop {
63160 let task = EXECUTOR
64161 . lock ( )
@@ -126,16 +223,4 @@ impl Executor {
126223 executor. tasks . push ( task. clone ( ) ) ;
127224 executor. ready_tasks . push_back ( task) ;
128225 }
129-
130- pub fn top_tasks ( n : usize ) -> Vec < ( u64 , & ' static str ) > {
131- let mut tasks: Vec < _ > = EXECUTOR
132- . lock ( )
133- . tasks
134- . iter ( )
135- . map ( |x| ( x. micros . load ( Ordering :: Relaxed ) , x. name ) )
136- . collect ( ) ;
137- tasks. sort_by_key ( |t| -( t. 0 as i64 ) ) ;
138- tasks. truncate ( n) ;
139- tasks
140- }
141226}
0 commit comments