Skip to content
This repository was archived by the owner on Mar 7, 2021. It is now read-only.

Commit 2fd4f7c

Browse files
authored
Fixed #2 -- use a stack buffer for formatting strings in printk (#7)
* Fixed #2 -- use a stack buffer for formatting strings in printk This avoids a malloc * fixes * more compilation fixes * oops, fix how we call this * sigh, weird scoping for macros * sigh, scoping, update use * Remove unused imports * fixed output length * rustfmt * apparently this isn't required? * simplify with cmp::min * review comments * all our printks are kern_info
1 parent 8ee77e9 commit 2fd4f7c

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

src/printk.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::cmp;
12
use core::fmt;
23

34
use types::c_int;
@@ -8,28 +9,53 @@ extern "C" {
89
fn printk_helper(s: *const u8, len: c_int) -> c_int;
910
}
1011

11-
impl fmt::Write for KernelConsole {
12+
pub fn printk(s: &[u8]) {
13+
// TODO: I believe printk never fails
14+
unsafe { printk_helper(s.as_ptr(), s.len() as c_int) };
15+
}
16+
17+
// From kernel/print/printk.c
18+
const LOG_LINE_MAX: usize = 1024 - 32;
19+
20+
pub struct LogLineWriter {
21+
data: [u8; LOG_LINE_MAX],
22+
pos: usize,
23+
}
24+
25+
impl LogLineWriter {
26+
pub fn new() -> LogLineWriter {
27+
LogLineWriter {
28+
data: [0u8; LOG_LINE_MAX],
29+
pos: 0,
30+
}
31+
}
32+
33+
pub fn as_bytes(&self) -> &[u8] {
34+
return &self.data[..self.pos];
35+
}
36+
}
37+
38+
impl fmt::Write for LogLineWriter {
1239
fn write_str(&mut self, s: &str) -> fmt::Result {
13-
// TODO: I believe printk never fails
14-
unsafe { printk_helper(s.as_ptr(), s.len() as c_int) };
15-
Ok(())
40+
let copy_len = cmp::min(LOG_LINE_MAX - self.pos, s.as_bytes().len());
41+
self.data[self.pos..self.pos + copy_len].copy_from_slice(&s.as_bytes()[..copy_len]);
42+
self.pos += copy_len;
43+
return Ok(());
1644
}
1745
}
1846

1947
#[macro_export]
2048
macro_rules! println {
2149
() => ({
22-
use ::core::fmt::Write;
23-
let _ = $crate::printk::KernelConsole.write_str("\x016\n");
50+
$crate::printk::printk("\n".as_bytes());
2451
});
2552
($fmt:expr) => ({
26-
use ::core::fmt::Write;
27-
let _ = $crate::printk::KernelConsole.write_str(concat!("\x016", $fmt, "\n"));
53+
$crate::printk::printk(concat!($fmt, "\n").as_bytes());
2854
});
2955
($fmt:expr, $($arg:tt)*) => ({
30-
use ::core::fmt::Write;
31-
// TODO: Don't allocate!
32-
let s = format!(concat!("\x016", $fmt, "\n"), $($arg)*);
33-
let _ = $crate::printk::KernelConsole.write_str(&s);
56+
use ::core::fmt;
57+
let mut writer = $crate::printk::LogLineWriter::new();
58+
let _ = fmt::write(&mut writer, format_args!(concat!($fmt, "\n"), $($arg)*)).unwrap();
59+
$crate::printk::printk(writer.as_bytes());
3460
});
3561
}

src/printk_helper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
int printk_helper(const unsigned char *s, int len)
44
{
5-
return printk("%.*s", len, (const char *)s);
5+
return printk(KERN_INFO "%.*s", len, (const char *)s);
66
}

0 commit comments

Comments
 (0)