Skip to content

Commit 6c22ed2

Browse files
committed
fix: solve the problem of format print
1 parent 28b99bd commit 6c22ed2

7 files changed

Lines changed: 76 additions & 7 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ riscv = "0.10"
4747
numeric-enum-macro = "0.2"
4848

4949
# 内部 crate 依赖
50-
tg-console = { path = "tg-console", version = "0.1.0-preview.1" }
50+
tg-console = { path = "tg-console", version = "0.1.0-preview.2" }
5151
tg-linker = { path = "tg-linker", version = "0.1.0-preview.2" }
5252
tg-syscall = { path = "tg-syscall", version = "0.1.0-preview.2" }
5353
tg-kernel-context = { path = "tg-kernel-context", version = "0.1.0-preview.1" }

tg-console/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "tg-console"
33
description = "Provides `print!`, `println!` and `log::Log` with customizable implementations for rCore tutorial."
4-
version = "0.1.0-preview.1"
4+
version = "0.1.0-preview.2"
55
edition = "2021"
66
authors = ["YdrMaster <ydrml@hotmail.com>"]
77
repository = "https://github.com/rcore-os/rCore-Tutorial-in-single-workspace"

tg-console/src/lib.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! 提供可定制实现的 `print!`、`println!` 和 `log::Log`。
1+
//! 提供可定制实现的 `print!`、`println!` 和 `log::Log`。
22
33
#![no_std]
44
#![deny(warnings, missing_docs)]
@@ -31,6 +31,66 @@ pub trait Console: Sync {
3131
/// 库找到输出的方法:保存一个对象引用,这是一种单例。
3232
static CONSOLE: Once<&'static dyn Console> = Once::new();
3333

34+
/// 打印缓冲区大小。
35+
const BUFFER_SIZE: usize = 64;
36+
37+
/// 打印缓冲区,用于收集格式化输出后一次性输出,避免抢占导致输出交错。
38+
struct PrintBuffer {
39+
buffer: [u8; BUFFER_SIZE],
40+
pos: usize,
41+
}
42+
43+
impl PrintBuffer {
44+
/// 创建一个新的打印缓冲区。
45+
const fn new() -> Self {
46+
Self {
47+
buffer: [0u8; BUFFER_SIZE],
48+
pos: 0,
49+
}
50+
}
51+
52+
/// 刷新缓冲区,将内容输出到控制台。
53+
fn flush(&mut self) {
54+
if self.pos > 0 {
55+
if let Some(console) = CONSOLE.get() {
56+
// SAFETY: buffer 中的内容是从 str 写入的,保证是有效的 UTF-8
57+
let s = unsafe { core::str::from_utf8_unchecked(&self.buffer[..self.pos]) };
58+
console.put_str(s);
59+
}
60+
self.pos = 0;
61+
}
62+
}
63+
64+
/// 写入字符串到缓冲区,必要时刷新。
65+
fn write(&mut self, s: &str) {
66+
let bytes = s.as_bytes();
67+
let mut offset = 0;
68+
69+
while offset < bytes.len() {
70+
let remaining_buffer = BUFFER_SIZE - self.pos;
71+
let remaining_input = bytes.len() - offset;
72+
let to_copy = remaining_buffer.min(remaining_input);
73+
74+
self.buffer[self.pos..self.pos + to_copy]
75+
.copy_from_slice(&bytes[offset..offset + to_copy]);
76+
self.pos += to_copy;
77+
offset += to_copy;
78+
79+
// 缓冲区满了,刷新
80+
if self.pos == BUFFER_SIZE {
81+
self.flush();
82+
}
83+
}
84+
}
85+
}
86+
87+
impl Write for PrintBuffer {
88+
fn write_str(&mut self, s: &str) -> fmt::Result {
89+
self.write(s);
90+
Ok(())
91+
}
92+
}
93+
3494
/// 用户调用这个函数设置输出的方法。
3595
pub fn init_console(console: &'static dyn Console) {
3696
CONSOLE.call_once(|| console);
@@ -65,10 +125,13 @@ pub fn test_log() {
65125
/// 打印。
66126
///
67127
/// 给宏用的,用户不会直接调它。
128+
/// 使用栈上缓冲区收集格式化输出,然后一次性输出到控制台。
68129
#[doc(hidden)]
69130
#[inline]
70131
pub fn _print(args: fmt::Arguments) {
71-
Logger.write_fmt(args).unwrap();
132+
let mut buffer = PrintBuffer::new();
133+
buffer.write_fmt(args).unwrap();
134+
buffer.flush();
72135
}
73136

74137
/// 格式化打印。

tg-kernel-vm/src/space/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ impl<Meta: VmMeta, M: PageManager<Meta>> AddressSpace<Meta, M> {
116116
}
117117
vpn = vpn + 1;
118118
}
119+
120+
// 刷新地址空间
121+
#[cfg(target_arch = "riscv64")]
122+
unsafe {
123+
core::arch::asm!("sfence.vma")
124+
};
119125
}
120126

121127
/// 查找指定 VPN 的 PTE 指针(用于修改)

user/src/bin/ch5b_usertest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const TESTS: &[&str] = &[
1212
"08power_3",
1313
"09power_5",
1414
"10power_7",
15-
"sbrk",
1615
"fork_exit",
1716
"forktest_simple",
1817
"12forktest",
18+
"sbrk",
1919
];
2020

2121
const TEST_NUM: usize = TESTS.len();

user/src/bin/ch6b_usertest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const TESTS: &[&str] = &[
1212
"08power_3",
1313
"09power_5",
1414
"10power_7",
15-
"sbrk",
1615
"fork_exit",
1716
"forktest_simple",
1817
"12forktest",
18+
"sbrk",
1919
"filetest_simple",
2020
"cat_filea",
2121
];

user/src/bin/ch7b_usertest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const TESTS: &[&str] = &[
1212
"08power_3",
1313
"09power_5",
1414
"10power_7",
15-
"sbrk",
1615
"fork_exit",
1716
"forktest_simple",
1817
"12forktest",
18+
"sbrk",
1919
"filetest_simple",
2020
"cat_filea",
2121
"sig_simple",

0 commit comments

Comments
 (0)