diff --git a/framework/jinux-frame/src/arch/x86/device/serial.rs b/framework/jinux-frame/src/arch/x86/device/serial.rs index b043be145..0dfe7d2a1 100644 --- a/framework/jinux-frame/src/arch/x86/device/serial.rs +++ b/framework/jinux-frame/src/arch/x86/device/serial.rs @@ -1,10 +1,11 @@ //! A port-mapped UART. Copied from uart_16550. use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess}; +use crate::sync::SpinLock; use crate::trap::IrqAllocateHandle; use alloc::{sync::Arc, vec::Vec}; use log::debug; -use spin::{Mutex, Once}; +use spin::Once; use trapframe::TrapFrame; bitflags::bitflags! { @@ -24,9 +25,9 @@ static SERIAL_MODEM_CTRL: IoPort = unsafe { IoPort::new(SERIAL_DATA_PORT + 4) }; static SERIAL_LINE_STS: IoPort = unsafe { IoPort::new(SERIAL_DATA_PORT + 5) }; -static CONSOLE_IRQ_CALLBACK: Once> = Once::new(); -static SERIAL_INPUT_CALLBACKS: Mutex>> = - Mutex::new(Vec::new()); +static CONSOLE_IRQ_CALLBACK: Once> = Once::new(); +static SERIAL_INPUT_CALLBACKS: SpinLock>> = + SpinLock::new(Vec::new()); /// Initializes the serial port. pub(crate) fn init() { @@ -56,7 +57,7 @@ pub fn register_serial_input_callback(f: impl Fn(u8) + Send + Sync + 'static) { pub(crate) fn callback_init() { let mut irq = crate::arch::x86::kernel::pic::allocate_irq(4).unwrap(); irq.on_active(handle_serial_input); - CONSOLE_IRQ_CALLBACK.call_once(|| Mutex::new(irq)); + CONSOLE_IRQ_CALLBACK.call_once(|| SpinLock::new(irq)); } pub(crate) fn register_serial_input_irq_handler(callback: F) @@ -72,10 +73,11 @@ where fn handle_serial_input(trap_frame: &TrapFrame) { // debug!("keyboard interrupt was met"); - if SERIAL_INPUT_CALLBACKS.is_locked() { + let lock = if let Some(lock) = SERIAL_INPUT_CALLBACKS.try_lock() { + lock + } else { return; - } - let lock = SERIAL_INPUT_CALLBACKS.lock(); + }; let received_char = receive_char().unwrap(); debug!("receive char = {:?}", received_char); for callback in lock.iter() { diff --git a/services/comps/framebuffer/src/lib.rs b/services/comps/framebuffer/src/lib.rs index 2949dc85f..1e86c34a6 100644 --- a/services/comps/framebuffer/src/lib.rs +++ b/services/comps/framebuffer/src/lib.rs @@ -12,8 +12,10 @@ use core::{ ops::{Index, IndexMut}, }; use font8x8::UnicodeFonts; -use jinux_frame::{config::PAGE_SIZE, mmio::Mmio, vm::VmIo, LimineFramebufferRequest}; -use spin::{Mutex, Once}; +use jinux_frame::{ + config::PAGE_SIZE, mmio::Mmio, sync::SpinLock, vm::VmIo, LimineFramebufferRequest, +}; +use spin::Once; #[init_component] fn framebuffer_init() -> Result<(), ComponentInitError> { @@ -21,7 +23,7 @@ fn framebuffer_init() -> Result<(), ComponentInitError> { Ok(()) } -pub(crate) static WRITER: Once> = Once::new(); +pub(crate) static WRITER: Once> = Once::new(); static FRAMEBUFFER_REUEST: LimineFramebufferRequest = LimineFramebufferRequest::new(0); pub(crate) fn init() { @@ -64,7 +66,7 @@ pub(crate) fn init() { }; writer.clear(); - WRITER.call_once(|| Mutex::new(writer)); + WRITER.call_once(|| SpinLock::new(writer)); } pub(crate) struct Writer { diff --git a/services/libs/jinux-std/src/device/mod.rs b/services/libs/jinux-std/src/device/mod.rs index 2f1887c58..97fc350c6 100644 --- a/services/libs/jinux-std/src/device/mod.rs +++ b/services/libs/jinux-std/src/device/mod.rs @@ -11,6 +11,7 @@ pub fn init() -> Result<()> { add_node(null, "null")?; let zero = Arc::new(zero::Zero); add_node(zero, "zero")?; + tty::init(); let tty = tty::get_n_tty().clone(); add_node(tty, "tty")?; Ok(()) diff --git a/services/libs/jinux-std/src/driver/tty.rs b/services/libs/jinux-std/src/device/tty/driver.rs similarity index 80% rename from services/libs/jinux-std/src/driver/tty.rs rename to services/libs/jinux-std/src/device/tty/driver.rs index 7256466cd..d9eb04a46 100644 --- a/services/libs/jinux-std/src/driver/tty.rs +++ b/services/libs/jinux-std/src/device/tty/driver.rs @@ -1,28 +1,30 @@ pub use jinux_frame::arch::x86::device::serial::register_serial_input_callback; +use spin::Once; use crate::{ device::tty::{get_n_tty, Tty}, prelude::*, }; -lazy_static! { - pub static ref TTY_DRIVER: Arc = { - let tty_driver = Arc::new(TtyDriver::new()); - // FIXME: install n_tty into tty_driver? - let n_tty = get_n_tty(); - tty_driver.install(n_tty.clone()); - tty_driver - }; +pub static TTY_DRIVER: Once> = Once::new(); + +pub(super) fn init() { + register_serial_input_callback(serial_input_callback); + let tty_driver = Arc::new(TtyDriver::new()); + // FIXME: install n_tty into tty_driver? + let n_tty = get_n_tty(); + tty_driver.install(n_tty.clone()); + TTY_DRIVER.call_once(|| tty_driver); } pub struct TtyDriver { - ttys: Mutex>>, + ttys: SpinLock>>, } impl TtyDriver { pub fn new() -> Self { Self { - ttys: Mutex::new(Vec::new()), + ttys: SpinLock::new(Vec::new()), } } @@ -70,9 +72,5 @@ fn serial_input_callback(item: u8) { } fn get_tty_driver() -> &'static TtyDriver { - &TTY_DRIVER -} - -pub fn init() { - register_serial_input_callback(serial_input_callback); + TTY_DRIVER.get().unwrap() } diff --git a/services/libs/jinux-std/src/device/tty/line_discipline.rs b/services/libs/jinux-std/src/device/tty/line_discipline.rs index 688e6ef46..c48e63a3e 100644 --- a/services/libs/jinux-std/src/device/tty/line_discipline.rs +++ b/services/libs/jinux-std/src/device/tty/line_discipline.rs @@ -15,13 +15,13 @@ const BUFFER_CAPACITY: usize = 4096; pub struct LineDiscipline { /// current line - current_line: RwLock, + current_line: SpinLock, /// The read buffer - read_buffer: Mutex>, + read_buffer: SpinLock>, /// The foreground process group - foreground: RwLock>, + foreground: SpinLock>, /// termios - termios: RwLock, + termios: SpinLock, /// Pollee pollee: Pollee, } @@ -65,17 +65,17 @@ impl LineDiscipline { /// create a new line discipline pub fn new() -> Self { Self { - current_line: RwLock::new(CurrentLine::new()), - read_buffer: Mutex::new(StaticRb::default()), - foreground: RwLock::new(None), - termios: RwLock::new(KernelTermios::default()), + current_line: SpinLock::new(CurrentLine::new()), + read_buffer: SpinLock::new(StaticRb::default()), + foreground: SpinLock::new(None), + termios: SpinLock::new(KernelTermios::default()), pollee: Pollee::new(IoEvents::empty()), } } /// push char to line discipline. This function should be called in input interrupt handler. pub fn push_char(&self, mut item: u8) { - let termios = self.termios.read(); + let termios = self.termios.lock(); if termios.contains_icrnl() { if item == b'\r' { item = b'\n' @@ -85,7 +85,7 @@ impl LineDiscipline { if item == *termios.get_special_char(CC_C_CHAR::VINTR) { // type Ctrl + C, signal SIGINT if termios.contains_isig() { - if let Some(fg) = *self.foreground.read() { + if let Some(fg) = *self.foreground.lock() { let kernel_signal = KernelSignal::new(SIGINT); let fg_group = process_table::pgid_to_process_group(fg).unwrap(); fg_group.kernel_signal(kernel_signal); @@ -94,7 +94,7 @@ impl LineDiscipline { } else if item == *termios.get_special_char(CC_C_CHAR::VQUIT) { // type Ctrl + \, signal SIGQUIT if termios.contains_isig() { - if let Some(fg) = *self.foreground.read() { + if let Some(fg) = *self.foreground.lock() { let kernel_signal = KernelSignal::new(SIGQUIT); let fg_group = process_table::pgid_to_process_group(fg).unwrap(); fg_group.kernel_signal(kernel_signal); @@ -102,17 +102,17 @@ impl LineDiscipline { } } else if item == *termios.get_special_char(CC_C_CHAR::VKILL) { // erase current line - self.current_line.write().drain(); + self.current_line.lock().drain(); } else if item == *termios.get_special_char(CC_C_CHAR::VERASE) { // type backspace - let mut current_line = self.current_line.write(); + let mut current_line = self.current_line.lock(); if !current_line.is_empty() { current_line.backspace(); } - } else if meet_new_line(item, &self.get_termios()) { + } else if meet_new_line(item, &self.termios()) { // a new line was met. We currently add the item to buffer. // when we read content, the item should be skipped if it's EOF. - let mut current_line = self.current_line.write(); + let mut current_line = self.current_line.lock(); current_line.push_char(item); let current_line_chars = current_line.drain(); for char in current_line_chars { @@ -120,7 +120,7 @@ impl LineDiscipline { } } else if item >= 0x20 && item < 0x7f { // printable character - self.current_line.write().push_char(item); + self.current_line.lock().push_char(item); } } else { // raw mode @@ -148,7 +148,7 @@ impl LineDiscipline { let ch = char::from(item); print!("{}", ch); } - let termios = self.termios.read(); + let termios = self.termios.lock(); if item == *termios.get_special_char(CC_C_CHAR::VERASE) { // write a space to overwrite current character let bytes: [u8; 3] = [b'\x08', b' ', b'\x08']; @@ -202,7 +202,7 @@ impl LineDiscipline { } let (vmin, vtime) = { - let termios = self.termios.read(); + let termios = self.termios.lock(); let vmin = *termios.get_special_char(CC_C_CHAR::VMIN); let vtime = *termios.get_special_char(CC_C_CHAR::VTIME); (vmin, vtime) @@ -246,10 +246,11 @@ impl LineDiscipline { let mut read_len = 0; for i in 0..max_read_len { if let Some(next_char) = buffer.pop() { - if self.termios.read().is_canonical_mode() { + let termios = self.termios.lock(); + if termios.is_canonical_mode() { // canonical mode, read until meet new line - if meet_new_line(next_char, &self.termios.read()) { - if !should_not_be_read(next_char, &self.termios.read()) { + if meet_new_line(next_char, &termios) { + if !should_not_be_read(next_char, &termios) { dst[i] = next_char; read_len += 1; } @@ -291,7 +292,7 @@ impl LineDiscipline { /// whether the current process belongs to foreground process group fn current_belongs_to_foreground(&self) -> bool { let current = current!(); - if let Some(fg_pgid) = *self.foreground.read() { + if let Some(fg_pgid) = *self.foreground.lock() { if let Some(process_group) = process_table::pgid_to_process_group(fg_pgid) { if process_group.contains_process(current.pid()) { return true; @@ -304,7 +305,7 @@ impl LineDiscipline { /// set foreground process group pub fn set_fg(&self, fg_pgid: Pgid) { - *self.foreground.write() = Some(fg_pgid); + *self.foreground.lock() = Some(fg_pgid); // Some background processes may be waiting on the wait queue, when set_fg, the background processes may be able to read. if self.is_readable() { self.pollee.add_events(IoEvents::IN); @@ -312,8 +313,8 @@ impl LineDiscipline { } /// get foreground process group id - pub fn get_fg(&self) -> Option { - *self.foreground.read() + pub fn fg_pgid(&self) -> Option { + *self.foreground.lock() } /// whether there is buffered data @@ -321,12 +322,12 @@ impl LineDiscipline { self.read_buffer.lock().len() == 0 } - pub fn get_termios(&self) -> KernelTermios { - *self.termios.read() + pub fn termios(&self) -> KernelTermios { + *self.termios.lock() } pub fn set_termios(&self, termios: KernelTermios) { - *self.termios.write() = termios; + *self.termios.lock() = termios; } } diff --git a/services/libs/jinux-std/src/device/tty/mod.rs b/services/libs/jinux-std/src/device/tty/mod.rs index b590efc82..8bde2ae5e 100644 --- a/services/libs/jinux-std/src/device/tty/mod.rs +++ b/services/libs/jinux-std/src/device/tty/mod.rs @@ -1,19 +1,24 @@ +use spin::Once; + +use self::driver::TtyDriver; use self::line_discipline::LineDiscipline; use super::*; -use crate::driver::tty::TtyDriver; use crate::fs::utils::{IoEvents, IoctlCmd, Poller}; use crate::prelude::*; use crate::process::Pgid; use crate::util::{read_val_from_user, write_val_to_user}; +pub mod driver; pub mod line_discipline; pub mod termio; -lazy_static! { - static ref N_TTY: Arc = { - let name = CString::new("console").unwrap(); - Arc::new(Tty::new(name)) - }; +static N_TTY: Once> = Once::new(); + +pub(super) fn init() { + let name = CString::new("console").unwrap(); + let tty = Arc::new(Tty::new(name)); + N_TTY.call_once(|| tty); + driver::init(); } pub struct Tty { @@ -22,7 +27,7 @@ pub struct Tty { /// line discipline ldisc: LineDiscipline, /// driver - driver: Mutex>, + driver: SpinLock>, } impl Tty { @@ -30,7 +35,7 @@ impl Tty { Tty { name, ldisc: LineDiscipline::new(), - driver: Mutex::new(Weak::new()), + driver: SpinLock::new(Weak::new()), } } @@ -79,14 +84,14 @@ impl Device for Tty { match cmd { IoctlCmd::TCGETS => { // Get terminal attributes - let termios = self.ldisc.get_termios(); + let termios = self.ldisc.termios(); trace!("get termios = {:?}", termios); write_val_to_user(arg, &termios)?; Ok(0) } IoctlCmd::TIOCGPGRP => { // FIXME: Get the process group ID of the foreground process group on this terminal. - let fg_pgid = self.ldisc.get_fg(); + let fg_pgid = self.ldisc.fg_pgid(); match fg_pgid { None => return_errno_with_message!(Errno::ENOENT, "No fg process group"), Some(fg_pgid) => { @@ -120,5 +125,5 @@ impl Device for Tty { /// FIXME: should we maintain a static console? pub fn get_n_tty() -> &'static Arc { - &N_TTY + N_TTY.get().unwrap() } diff --git a/services/libs/jinux-std/src/driver/mod.rs b/services/libs/jinux-std/src/driver/mod.rs index f43971caf..de9025ad2 100644 --- a/services/libs/jinux-std/src/driver/mod.rs +++ b/services/libs/jinux-std/src/driver/mod.rs @@ -1,5 +1,3 @@ -pub mod tty; - use jinux_input::INPUT_COMPONENT; use log::info; @@ -8,7 +6,6 @@ pub fn init() { for comp in INPUT_COMPONENT.get().unwrap().get_input_device() { info!("input device name:{}", comp.name()); } - tty::init(); } #[allow(unused)] diff --git a/services/libs/jinux-std/src/prelude.rs b/services/libs/jinux-std/src/prelude.rs index c3a7871bd..701fe1b13 100644 --- a/services/libs/jinux-std/src/prelude.rs +++ b/services/libs/jinux-std/src/prelude.rs @@ -18,6 +18,7 @@ pub(crate) use core::ffi::CStr; pub(crate) use int_to_c_enum::TryFromInt; pub(crate) use jinux_frame::config::PAGE_SIZE; // pub(crate) use jinux_frame::sync::{Mutex, MutexGuard}; +pub(crate) use jinux_frame::sync::{SpinLock, SpinLockGuard}; pub(crate) use jinux_frame::vm::Vaddr; pub(crate) use jinux_frame::{print, println}; pub(crate) use log::{debug, error, info, trace, warn};