11use alloc:: boxed:: Box ;
22use alloc:: collections:: BTreeMap ;
3- use alloc:: rc:: Rc ;
43use alloc:: vec:: Vec ;
5- use core:: cell:: RefCell ;
4+ use core:: cell:: { Cell , RefCell } ;
5+ use core:: fmt:: Write ;
66use core:: mem;
77use core:: net:: SocketAddrV4 ;
88
@@ -12,13 +12,13 @@ use lz4_flex::decompress;
1212use pixie_shared:: chunk_codec:: Decoder ;
1313use pixie_shared:: util:: BytesFmt ;
1414use pixie_shared:: { ChunkHash , Image , TcpRequest , UdpRequest , CHUNKS_PORT , MAX_CHUNK_SIZE } ;
15- use uefi:: proto:: console:: text:: Color ;
1615
1716use crate :: os:: boot_options:: BootOptions ;
1817use crate :: os:: error:: { Error , Result } ;
1918use crate :: os:: executor:: Executor ;
2019use crate :: os:: net:: { TcpStream , UdpSocket , ETH_PACKET_SIZE } ;
21- use crate :: os:: { disk, memory, UefiOS } ;
20+ use crate :: os:: ui:: { update_content, DrawArea } ;
21+ use crate :: os:: { disk, memory} ;
2222use crate :: MIN_MEMORY ;
2323
2424async fn fetch_image ( stream : & TcpStream ) -> Result < Image > {
@@ -32,6 +32,7 @@ async fn fetch_image(stream: &TcpStream) -> Result<Image> {
3232 Ok ( postcard:: from_bytes ( & buf) ?)
3333}
3434
35+ #[ derive( Clone , PartialEq , Eq ) ]
3536struct Stats {
3637 chunks : usize ,
3738 unique : usize ,
@@ -75,7 +76,7 @@ fn handle_packet(
7576 Ok ( Some ( ( pos, data) ) )
7677}
7778
78- pub async fn flash ( os : UefiOS , server_addr : SocketAddrV4 ) -> Result < ( ) > {
79+ pub async fn flash ( server_addr : SocketAddrV4 ) -> Result < ( ) > {
7980 let stream = TcpStream :: connect ( server_addr) . await ?;
8081 let image = fetch_image ( & stream) . await ?;
8182 stream. shutdown ( ) . await ;
@@ -93,49 +94,43 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
9394
9495 info ! ( "Obtained chunks; {} distinct chunks" , chunks_info. len( ) ) ;
9596
96- let stats = Rc :: new ( RefCell :: new ( Stats {
97+ let stats = RefCell :: new ( Stats {
9798 chunks : image. disk . len ( ) ,
9899 unique : chunks_info. len ( ) ,
99100 fetch : 0 ,
100101 recv : 0 ,
101102 pack_recv : 0 ,
102103 requested : 0 ,
103- } ) ) ;
104-
105- let stats2 = stats. clone ( ) ;
106- os. set_ui_drawer ( move |os| {
107- os. write_with_color (
108- & format ! ( "{} total chunks\n " , stats2. borrow( ) . chunks) ,
109- Color :: White ,
110- Color :: Black ,
111- ) ;
112- os. write_with_color (
113- & format ! ( "{} unique chunks\n " , stats2. borrow( ) . unique) ,
114- Color :: White ,
115- Color :: Black ,
116- ) ;
117- os. write_with_color (
118- & format ! ( "{} chunks to fetch\n " , stats2. borrow( ) . fetch) ,
119- Color :: White ,
120- Color :: Black ,
121- ) ;
122- os. write_with_color (
123- & format ! ( "{} chunks received\n " , stats2. borrow( ) . recv) ,
124- Color :: White ,
125- Color :: Black ,
126- ) ;
127- os. write_with_color (
128- & format ! ( "{} packets received\n " , stats2. borrow( ) . pack_recv) ,
129- Color :: White ,
130- Color :: Black ,
131- ) ;
132- os. write_with_color (
133- & format ! ( "{} chunks requested\n " , stats2. borrow( ) . requested) ,
134- Color :: White ,
135- Color :: Black ,
136- ) ;
137104 } ) ;
138105
106+ let draw = |draw_area : & mut DrawArea | {
107+ draw_area. clear ( ) ;
108+ writeln ! ( draw_area, "{} total chunks" , stats. borrow( ) . chunks) . unwrap ( ) ;
109+ writeln ! ( draw_area, "{} unique chunks" , stats. borrow( ) . unique) . unwrap ( ) ;
110+ writeln ! ( draw_area, "{} chunks to fetch" , stats. borrow( ) . fetch) . unwrap ( ) ;
111+ writeln ! ( draw_area, "{} chunks received" , stats. borrow( ) . recv) . unwrap ( ) ;
112+ writeln ! ( draw_area, "{} packets received" , stats. borrow( ) . pack_recv) . unwrap ( ) ;
113+ writeln ! ( draw_area, "{} chunks requested" , stats. borrow( ) . requested) . unwrap ( ) ;
114+ } ;
115+
116+ update_content ( draw) ;
117+
118+ let done = Cell :: new ( false ) ;
119+
120+ let draw_task = async {
121+ let mut last_stats = stats. borrow ( ) . clone ( ) ;
122+ while !done. get ( ) {
123+ Executor :: sleep_us ( 100_000 ) . await ;
124+ let stats = stats. borrow ( ) . clone ( ) ;
125+ if stats == last_stats {
126+ continue ;
127+ }
128+ update_content ( draw) ;
129+ last_stats = stats;
130+ }
131+ Ok ( ( ) )
132+ } ;
133+
139134 let mut disk = disk:: Disk :: largest ( ) ;
140135
141136 for ( hash, ( size, csize, pos) ) in mem:: take ( & mut chunks_info) {
@@ -158,6 +153,7 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
158153 chunks_info. insert ( hash, ( size, csize, pos) ) ;
159154 stats. borrow_mut ( ) . fetch = chunks_info. len ( ) ;
160155 }
156+ update_content ( draw) ;
161157 }
162158
163159 info ! ( "Disk scanned; {} chunks to fetch" , stats. borrow( ) . fetch) ;
@@ -226,10 +222,11 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
226222 . send_to ( server_addr, & postcard:: to_allocvec ( & msg) ?)
227223 . await ?;
228224 }
225+ done. set ( true ) ;
229226 Ok ( ( ) )
230227 } ;
231228
232- let ( ( ) , ( ) ) = futures:: try_join!( task1, task2) ?;
229+ let ( ( ) , ( ) , ( ) ) = futures:: try_join!( task1, task2, draw_task ) ?;
233230
234231 info ! ( "Fetch complete, updating boot options" ) ;
235232
0 commit comments