Reduce the number of syscalls made by the console in libtock-rs.
This commit is contained in:
95
patches/libtock-rs/08-buffered-console.patch
Normal file
95
patches/libtock-rs/08-buffered-console.patch
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
diff --git a/src/console.rs b/src/console.rs
|
||||||
|
index ecd7ad1..785de01 100644
|
||||||
|
--- a/src/console.rs
|
||||||
|
+++ b/src/console.rs
|
||||||
|
@@ -16,33 +16,58 @@ mod allow_nr {
|
||||||
|
pub const SHARE_BUFFER: usize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+const BUFFER_SIZE: usize = 64;
|
||||||
|
+
|
||||||
|
pub struct Console {
|
||||||
|
- allow_buffer: [u8; 64],
|
||||||
|
+ allow_buffer: [u8; BUFFER_SIZE],
|
||||||
|
+ count_pending: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Console {
|
||||||
|
pub fn new() -> Console {
|
||||||
|
Console {
|
||||||
|
- allow_buffer: [0; 64],
|
||||||
|
+ allow_buffer: [0; BUFFER_SIZE],
|
||||||
|
+ count_pending: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ fn is_empty(&self) -> bool {
|
||||||
|
+ self.count_pending == 0
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fn is_full(&self) -> bool {
|
||||||
|
+ self.allow_buffer.len() == self.count_pending
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fn available_len(&self) -> usize {
|
||||||
|
+ self.allow_buffer.len() - self.count_pending
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
pub fn write<S: AsRef<[u8]>>(&mut self, text: S) {
|
||||||
|
let mut not_written_yet = text.as_ref();
|
||||||
|
while !not_written_yet.is_empty() {
|
||||||
|
- let num_bytes_to_print = self.allow_buffer.len().min(not_written_yet.len());
|
||||||
|
- self.allow_buffer[..num_bytes_to_print]
|
||||||
|
+ let num_bytes_to_print = self.available_len().min(not_written_yet.len());
|
||||||
|
+ self.allow_buffer[self.count_pending..(self.count_pending + num_bytes_to_print)]
|
||||||
|
.copy_from_slice(¬_written_yet[..num_bytes_to_print]);
|
||||||
|
- self.flush(num_bytes_to_print);
|
||||||
|
+ self.count_pending += num_bytes_to_print;
|
||||||
|
+
|
||||||
|
+ if self.is_full() {
|
||||||
|
+ self.flush();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
not_written_yet = ¬_written_yet[num_bytes_to_print..];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn flush(&mut self, num_bytes_to_print: usize) {
|
||||||
|
+ fn flush(&mut self) {
|
||||||
|
+ let count = self.count_pending;
|
||||||
|
+ // Clear the buffer even in case of error, to avoid an infinite loop.
|
||||||
|
+ self.count_pending = 0;
|
||||||
|
+
|
||||||
|
let result = syscalls::allow(
|
||||||
|
DRIVER_NUMBER,
|
||||||
|
allow_nr::SHARE_BUFFER,
|
||||||
|
- &mut self.allow_buffer[..num_bytes_to_print],
|
||||||
|
+ &mut self.allow_buffer[..count],
|
||||||
|
);
|
||||||
|
if result.is_err() {
|
||||||
|
return;
|
||||||
|
@@ -59,8 +84,7 @@ impl Console {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- let result_code =
|
||||||
|
- unsafe { syscalls::command(DRIVER_NUMBER, command_nr::WRITE, num_bytes_to_print, 0) };
|
||||||
|
+ let result_code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::WRITE, count, 0) };
|
||||||
|
if result_code < 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -69,6 +93,14 @@ impl Console {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+impl Drop for Console {
|
||||||
|
+ fn drop(&mut self) {
|
||||||
|
+ if !self.is_empty() {
|
||||||
|
+ self.flush();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
impl fmt::Write for Console {
|
||||||
|
fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
|
||||||
|
self.write(string);
|
||||||
Reference in New Issue
Block a user