Skip to content

Commit bc91846

Browse files
committed
feat(kernel): 使用ringbuf替换键盘驱动中的Vec缓冲区
1 parent 47634de commit bc91846

File tree

3 files changed

+98
-55
lines changed

3 files changed

+98
-55
lines changed

kernel/Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kernel/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ uart_16550 = "0.4.0"
2424
x86_64 = "0.15.2"
2525
pc-keyboard = "0.7.0"
2626
acpi = { version = "6.0.1", features = ["alloc", "aml"] }
27+
ringbuf = { version = "0.4.8", default-features = false, features = ["alloc"] }
2728

2829
[features]
2930
ttf = ["dep:ab_glyph", "dep:libm"]

kernel/src/drivers/input/keyboard.rs

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ extern crate alloc;
22
use crate::drivers::{CharDevice, Device, DeviceError, DeviceInner, DeviceType, SharedDeviceOps};
33
use alloc::string::String;
44
use alloc::sync::Arc;
5-
use alloc::vec::Vec;
65
use pc_keyboard::{
76
layouts, DecodedKey, HandleControl, KeyCode, KeyState, Keyboard as PcKeyboard, ScancodeSet1,
87
};
8+
use ringbuf::{traits::*, HeapRb};
99
use spin::Mutex;
1010

1111
// 缓冲区大小(增加到256字节)
@@ -117,7 +117,6 @@ pub struct KeyboardInner {
117117
pc_keyboard: PcKeyboard<layouts::Us104Key, ScancodeSet1>,
118118
enabled: bool,
119119
nonblocking: bool,
120-
buffer: Vec<char>,
121120
modifiers: ModifierState,
122121
leds: LedState,
123122
mode: KeyboardMode,
@@ -151,6 +150,8 @@ fn send_keyboard_command(command: u8, data: u8) {
151150

152151
pub struct Keyboard {
153152
inner: Mutex<KeyboardInner>,
153+
producer: Mutex<ringbuf::wrap::caching::Caching<Arc<HeapRb<char>>, true, false>>,
154+
consumer: Mutex<ringbuf::wrap::caching::Caching<Arc<HeapRb<char>>, false, true>>,
154155
name: String,
155156
}
156157

@@ -164,7 +165,6 @@ impl KeyboardInner {
164165
),
165166
enabled: true,
166167
nonblocking: false,
167-
buffer: Vec::with_capacity(BUFFER_SIZE),
168168
modifiers: ModifierState::default(),
169169
leds: LedState::default(),
170170
mode: KeyboardMode::Unicode,
@@ -210,26 +210,16 @@ impl KeyboardInner {
210210
_ => {}
211211
}
212212
}
213-
214-
/// 添加字符到缓冲区(使用滑动窗口策略)
215-
fn push_char(&mut self, c: char) {
216-
if self.buffer.len() >= BUFFER_SIZE {
217-
// 缓冲区满时,丢弃最旧的数据
218-
self.buffer.remove(0);
219-
}
220-
self.buffer.push(c);
221-
}
222-
223-
/// 清空缓冲区
224-
fn clear_buffer(&mut self) {
225-
self.buffer.clear();
226-
}
227213
}
228214

229215
impl Default for Keyboard {
230216
fn default() -> Self {
217+
let rb = HeapRb::<char>::new(BUFFER_SIZE);
218+
let (prod, cons) = rb.split();
231219
Self {
232220
inner: Mutex::new(KeyboardInner::new()),
221+
producer: Mutex::new(prod),
222+
consumer: Mutex::new(cons),
233223
name: String::from("keyboard"),
234224
}
235225
}
@@ -260,38 +250,51 @@ impl Keyboard {
260250
x86_64::instructions::interrupts::without_interrupts(|| self.inner.lock().nonblocking)
261251
}
262252

253+
/// 添加字符到环形缓冲区
254+
fn push_char(&self, c: char) {
255+
let mut producer = self.producer.lock();
256+
// 缓冲区满时,直接丢弃字符以避免在中断上下文中进行复杂的同步或死锁风险
257+
// 256 字节对于键盘来说通常足够大
258+
let _ = producer.try_push(c);
259+
}
260+
263261
pub fn handle_scancode(&self, scancode: u8) {
264-
let mut inner = self.inner.lock();
265-
if !inner.enabled {
266-
return;
267-
}
262+
let mut key_to_push = None;
263+
{
264+
let mut inner = self.inner.lock();
265+
if !inner.enabled {
266+
return;
267+
}
268268

269-
if let Ok(Some(key_event)) = inner.pc_keyboard.add_byte(scancode) {
270-
// 更新修饰键状态
271-
inner.update_modifier(key_event.code, key_event.state);
269+
if let Ok(Some(key_event)) = inner.pc_keyboard.add_byte(scancode) {
270+
// 更新修饰键状态
271+
inner.update_modifier(key_event.code, key_event.state);
272272

273-
if let Some(key) = inner.pc_keyboard.process_keyevent(key_event) {
274-
match inner.mode {
275-
KeyboardMode::Unicode => {
276-
if let DecodedKey::Unicode(character) = key {
277-
inner.push_char(character);
273+
if let Some(key) = inner.pc_keyboard.process_keyevent(key_event) {
274+
match inner.mode {
275+
KeyboardMode::Unicode => {
276+
if let DecodedKey::Unicode(character) = key {
277+
key_to_push = Some(character);
278+
}
278279
}
279-
}
280-
KeyboardMode::Raw => {
281-
// 原始模式:将扫描码直接放入缓冲区
282-
let raw_char = scancode as char;
283-
inner.push_char(raw_char);
284-
}
285-
KeyboardMode::MediumRaw => {
286-
// 中等原始模式:处理后的键码
287-
if let DecodedKey::RawKey(key_code) = key {
288-
let code_char = (key_code as u8) as char;
289-
inner.push_char(code_char);
280+
KeyboardMode::Raw => {
281+
// 原始模式:将扫描码直接放入缓冲区
282+
key_to_push = Some(scancode as char);
283+
}
284+
KeyboardMode::MediumRaw => {
285+
// 中等原始模式:处理后的键码
286+
if let DecodedKey::RawKey(key_code) = key {
287+
key_to_push = Some((key_code as u8) as char);
288+
}
290289
}
291290
}
292291
}
293292
}
294293
}
294+
295+
if let Some(c) = key_to_push {
296+
self.push_char(c);
297+
}
295298
}
296299

297300
pub fn get_modifier_state(&self) -> ModifierState {
@@ -315,7 +318,8 @@ impl Keyboard {
315318

316319
pub fn clear_buffer(&self) {
317320
x86_64::instructions::interrupts::without_interrupts(|| {
318-
self.inner.lock().clear_buffer();
321+
let mut consumer = self.consumer.lock();
322+
while consumer.try_pop().is_some() {}
319323
});
320324
}
321325

@@ -405,17 +409,24 @@ impl SharedDeviceOps for Keyboard {
405409
impl CharDevice for Keyboard {
406410
fn read(&self, buf: &mut [u8]) -> Result<usize, DeviceError> {
407411
x86_64::instructions::interrupts::without_interrupts(|| {
408-
let mut inner = self.inner.lock();
412+
let nonblocking = self.inner.lock().nonblocking;
413+
let mut consumer = self.consumer.lock();
409414

410415
// 非阻塞模式检查
411-
if inner.nonblocking && inner.buffer.is_empty() {
416+
if nonblocking && consumer.is_empty() {
412417
return Err(DeviceError::WouldBlock);
413418
}
414419

415420
let mut read_count = 0;
416421

417-
while read_count < buf.len() && !inner.buffer.is_empty() {
418-
let c = inner.buffer.remove(0);
422+
while read_count < buf.len() && !consumer.is_empty() {
423+
// Peek the front character
424+
let (s1, s2): (&[char], &[char]) = consumer.as_slices();
425+
let c = if let Some(&c) = s1.first().or_else(|| s2.first()) {
426+
c
427+
} else {
428+
break;
429+
};
419430

420431
let mut char_buf = [0u8; 4];
421432
let char_str = c.encode_utf8(&mut char_buf);
@@ -424,9 +435,10 @@ impl CharDevice for Keyboard {
424435
if read_count + bytes.len() <= buf.len() {
425436
buf[read_count..read_count + bytes.len()].copy_from_slice(bytes);
426437
read_count += bytes.len();
438+
// Successfully read, pop it
439+
consumer.try_pop();
427440
} else {
428-
// 缓冲区空间不足,将字符重新放回
429-
inner.buffer.insert(0, c);
441+
// 缓冲区空间不足
430442
break;
431443
}
432444
}
@@ -445,16 +457,17 @@ impl CharDevice for Keyboard {
445457

446458
fn peek(&self, buf: &mut [u8]) -> Result<usize, DeviceError> {
447459
x86_64::instructions::interrupts::without_interrupts(|| {
448-
let inner = self.inner.lock();
460+
let consumer = self.consumer.lock();
449461

450-
if inner.buffer.is_empty() {
462+
if consumer.is_empty() {
451463
return Err(DeviceError::WouldBlock);
452464
}
453465

454466
let mut read_count = 0;
455-
let buffer_copy = inner.buffer.clone();
456467

457-
for c in buffer_copy.iter().take(buf.len()) {
468+
// 使用 as_slices 遍历环形缓冲区
469+
let (s1, s2): (&[char], &[char]) = consumer.as_slices();
470+
for &c in s1.iter().chain(s2.iter()) {
458471
let mut char_buf = [0u8; 4];
459472
let char_str = c.encode_utf8(&mut char_buf);
460473
let bytes = char_str.as_bytes();
@@ -472,10 +485,7 @@ impl CharDevice for Keyboard {
472485
}
473486

474487
fn has_data(&self) -> bool {
475-
x86_64::instructions::interrupts::without_interrupts(|| {
476-
let inner = self.inner.lock();
477-
!inner.buffer.is_empty()
478-
})
488+
x86_64::instructions::interrupts::without_interrupts(|| !self.consumer.lock().is_empty())
479489
}
480490

481491
fn set_nonblocking(&self, nonblocking: bool) -> Result<(), DeviceError> {

0 commit comments

Comments
 (0)