Skip to content

Commit 80ad309

Browse files
committed
Split off UI from OS and redesign it.
This gets rid of the last parts of the OS struct.
1 parent c2ea82d commit 80ad309

13 files changed

Lines changed: 594 additions & 421 deletions

File tree

pixie-uefi/src/flash.rs

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ use lz4_flex::decompress;
1212
use pixie_shared::chunk_codec::Decoder;
1313
use pixie_shared::util::BytesFmt;
1414
use pixie_shared::{ChunkHash, Image, TcpRequest, UdpRequest, CHUNKS_PORT, MAX_CHUNK_SIZE};
15-
use uefi::proto::console::text::Color;
1615

1716
use crate::os::boot_options::BootOptions;
1817
use crate::os::error::{Error, Result};
1918
use crate::os::executor::Executor;
2019
use crate::os::net::{TcpStream, UdpSocket, ETH_PACKET_SIZE};
21-
use crate::os::{disk, memory, UefiOS};
20+
use crate::os::{disk, memory};
2221
use crate::MIN_MEMORY;
2322

2423
async fn fetch_image(stream: &TcpStream) -> Result<Image> {
@@ -75,7 +74,7 @@ fn handle_packet(
7574
Ok(Some((pos, data)))
7675
}
7776

78-
pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
77+
pub async fn flash(server_addr: SocketAddrV4) -> Result<()> {
7978
let stream = TcpStream::connect(server_addr).await?;
8079
let image = fetch_image(&stream).await?;
8180
stream.shutdown().await;
@@ -103,37 +102,14 @@ pub async fn flash(os: UefiOS, server_addr: SocketAddrV4) -> Result<()> {
103102
}));
104103

105104
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-
);
105+
crate::os::ui::set_content_drawer(move |draw_area| {
106+
draw_area.clear();
107+
draw_area.writeln(&format!("{} total chunks", stats2.borrow().chunks));
108+
draw_area.writeln(&format!("{} unique chunks", stats2.borrow().unique));
109+
draw_area.writeln(&format!("{} chunks to fetch", stats2.borrow().fetch));
110+
draw_area.writeln(&format!("{} chunks received", stats2.borrow().recv));
111+
draw_area.writeln(&format!("{} packets received", stats2.borrow().pack_recv));
112+
draw_area.writeln(&format!("{} chunks requested", stats2.borrow().requested));
137113
});
138114

139115
let mut disk = disk::Disk::largest();

pixie-uefi/src/main.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use crate::flash::flash;
1616
use crate::os::error::{Error, Result};
1717
use crate::os::executor::Executor;
1818
use crate::os::net::{TcpStream, UdpSocket, ETH_PACKET_SIZE};
19-
use crate::os::UefiOS;
2019
use crate::register::register;
2120
use crate::store::store;
2221

@@ -96,7 +95,7 @@ async fn complete_action(stream: &TcpStream) -> Result<()> {
9695
Ok(())
9796
}
9897

99-
async fn run(os: UefiOS) -> Result<()> {
98+
async fn run() -> Result<()> {
10099
let server = server_discover().await?;
101100

102101
let mut last_was_wait = false;
@@ -114,7 +113,7 @@ async fn run(os: UefiOS) -> Result<()> {
114113

115114
loop {
116115
// Clear any UI drawer.
117-
os.set_ui_drawer(|_| {});
116+
os::ui::set_content_drawer(|_| {});
118117

119118
if !last_was_wait {
120119
log::debug!("Sending request for command");
@@ -147,9 +146,9 @@ async fn run(os: UefiOS) -> Result<()> {
147146
Action::Boot => power_control::reboot_to_os().await,
148147
Action::Restart => {}
149148
Action::Shutdown => shutdown().await,
150-
Action::Register => register(os, server).await?,
151-
Action::Store => store(os, server).await?,
152-
Action::Flash => flash(os, server).await?,
149+
Action::Register => register(server).await?,
150+
Action::Store => store(server).await?,
151+
Action::Flash => flash(server).await?,
153152
}
154153

155154
let tcp = TcpStream::connect(server).await?;
@@ -167,5 +166,5 @@ async fn run(os: UefiOS) -> Result<()> {
167166

168167
#[entry]
169168
fn main() -> Status {
170-
UefiOS::start(run)
169+
os::start(run)
171170
}

pixie-uefi/src/os/disk.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ use uefi::boot::{OpenProtocolParams, ScopedProtocol};
77
use uefi::proto::media::block::BlockIO;
88
use uefi::Handle;
99

10-
use crate::os::executor::Executor;
11-
1210
use super::error::Result;
11+
use crate::os::executor::Executor;
1312

1413
fn open_disk(handle: Handle) -> Result<ScopedProtocol<BlockIO>> {
1514
let image_handle = uefi::boot::image_handle();

pixie-uefi/src/os/executor.rs

Lines changed: 97 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ use core::future::{poll_fn, Future};
77
use core::pin::Pin;
88
use core::sync::atomic::{AtomicBool, AtomicU64, Ordering};
99
use core::task::{Context, Poll, Waker};
10+
1011
use spin::Mutex;
1112
use uefi::boot::{EventType, TimerTrigger, Tpl};
13+
use uefi::proto::console::text::Color;
1214

1315
use crate::os::timer::Timer;
16+
use crate::os::ui::DrawArea;
1417

1518
struct 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

2731
impl 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

6065
impl 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
}

pixie-uefi/src/os/input.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use core::future::{poll_fn, Future};
2+
use core::task::Poll;
3+
4+
use spin::lazy::Lazy;
5+
use spin::Mutex;
6+
use uefi::boot::ScopedProtocol;
7+
use uefi::proto::console::text::{Input, Key};
8+
9+
use crate::os::error::Result;
10+
use crate::os::send_wrapper::SendWrapper;
11+
12+
static INPUT: Lazy<Mutex<SendWrapper<ScopedProtocol<Input>>>> = Lazy::new(|| {
13+
let input_handles = uefi::boot::find_handles::<Input>().unwrap();
14+
let input = uefi::boot::open_protocol_exclusive::<Input>(input_handles[0]).unwrap();
15+
Mutex::new(SendWrapper(input))
16+
});
17+
18+
pub fn read_key() -> impl Future<Output = Result<Key>> {
19+
poll_fn(move |cx| {
20+
let key = INPUT.lock().read_key();
21+
if let Err(e) = key {
22+
return Poll::Ready(Err(e.into()));
23+
}
24+
let key = key.unwrap();
25+
if let Some(key) = key {
26+
return Poll::Ready(Ok(key));
27+
}
28+
cx.waker().wake_by_ref();
29+
Poll::Pending
30+
})
31+
}

0 commit comments

Comments
 (0)