1 //! tty刷新内核线程 2 3 use alloc::{string::ToString, sync::Arc}; 4 use kdepends::thingbuf::StaticThingBuf; 5 6 use crate::{ 7 arch::sched::sched, 8 process::{ 9 kthread::{KernelThreadClosure, KernelThreadMechanism}, 10 ProcessControlBlock, ProcessFlags, 11 }, 12 }; 13 14 use super::tty_port::current_tty_port; 15 16 /// 用于缓存键盘输入的缓冲区 17 static KEYBUF: StaticThingBuf<u8, 512> = StaticThingBuf::new(); 18 19 static mut TTY_REFRESH_THREAD: Option<Arc<ProcessControlBlock>> = None; 20 21 pub(super) fn tty_flush_thread_init() { 22 let closure = 23 KernelThreadClosure::StaticEmptyClosure((&(tty_refresh_thread as fn() -> i32), ())); 24 let pcb = KernelThreadMechanism::create_and_run(closure, "tty_refresh".to_string()) 25 .ok_or("") 26 .expect("create tty_refresh thread failed"); 27 unsafe { 28 TTY_REFRESH_THREAD = Some(pcb); 29 } 30 } 31 32 fn tty_refresh_thread() -> i32 { 33 const TO_DEQUEUE_MAX: usize = 256; 34 loop { 35 if KEYBUF.is_empty() { 36 // 如果缓冲区为空,就休眠 37 unsafe { 38 TTY_REFRESH_THREAD 39 .as_ref() 40 .unwrap() 41 .flags() 42 .insert(ProcessFlags::NEED_SCHEDULE) 43 }; 44 45 sched(); 46 } 47 48 let to_dequeue = core::cmp::min(KEYBUF.len(), TO_DEQUEUE_MAX); 49 if to_dequeue == 0 { 50 continue; 51 } 52 let mut data = [0u8; TO_DEQUEUE_MAX]; 53 for i in 0..to_dequeue { 54 data[i] = KEYBUF.pop().unwrap(); 55 } 56 57 let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue); 58 } 59 } 60 61 /// 发送数据到tty刷新线程 62 pub fn send_to_tty_refresh_thread(data: &[u8]) { 63 for i in 0..data.len() { 64 KEYBUF.push(data[i]).ok(); 65 } 66 } 67