mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 01:13:23 +00:00
Refactor tty driver using the work queue
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
7419f6b56b
commit
d28f0db419
@ -19,7 +19,7 @@ const BUFFER_CAPACITY: usize = 4096;
|
|||||||
pub struct PtyMaster {
|
pub struct PtyMaster {
|
||||||
ptmx: Arc<dyn Inode>,
|
ptmx: Arc<dyn Inode>,
|
||||||
index: u32,
|
index: u32,
|
||||||
output: LineDiscipline,
|
output: Arc<LineDiscipline>,
|
||||||
input: SpinLock<HeapRb<u8>>,
|
input: SpinLock<HeapRb<u8>>,
|
||||||
/// The state of input buffer
|
/// The state of input buffer
|
||||||
pollee: Pollee,
|
pollee: Pollee,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use crate::fs::utils::{IoEvents, Pollee, Poller};
|
use crate::fs::utils::{IoEvents, Pollee, Poller};
|
||||||
use crate::process::signal::constants::{SIGINT, SIGQUIT};
|
use crate::process::signal::constants::{SIGINT, SIGQUIT};
|
||||||
use crate::process::ProcessGroup;
|
use crate::process::ProcessGroup;
|
||||||
|
use crate::thread::work_queue::work_item::WorkItem;
|
||||||
|
use crate::thread::work_queue::{submit_work_item, WorkPriority};
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
process::{signal::signals::kernel::KernelSignal, Pgid},
|
process::{signal::signals::kernel::KernelSignal, Pgid},
|
||||||
@ -29,6 +31,10 @@ pub struct LineDiscipline {
|
|||||||
winsize: SpinLock<WinSize>,
|
winsize: SpinLock<WinSize>,
|
||||||
/// Pollee
|
/// Pollee
|
||||||
pollee: Pollee,
|
pollee: Pollee,
|
||||||
|
/// work item
|
||||||
|
work_item: Arc<WorkItem>,
|
||||||
|
/// Parameters used by a work item.
|
||||||
|
work_item_para: Arc<SpinLock<LineDisciplineWorkPara>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -67,23 +73,27 @@ impl CurrentLine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LineDiscipline {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LineDiscipline {
|
impl LineDiscipline {
|
||||||
/// Create a new line discipline
|
/// Create a new line discipline
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Arc<Self> {
|
||||||
Self {
|
Arc::new_cyclic(|line_ref: &Weak<LineDiscipline>| {
|
||||||
current_line: SpinLock::new(CurrentLine::new()),
|
let line_discipline = line_ref.clone();
|
||||||
read_buffer: SpinLock::new(StaticRb::default()),
|
let work_item = Arc::new(WorkItem::new(Box::new(move || {
|
||||||
foreground: SpinLock::new(Weak::new()),
|
if let Some(line_discipline) = line_discipline.upgrade() {
|
||||||
termios: SpinLock::new(KernelTermios::default()),
|
line_discipline.update_readable_state_after();
|
||||||
winsize: SpinLock::new(WinSize::default()),
|
}
|
||||||
pollee: Pollee::new(IoEvents::empty()),
|
})));
|
||||||
}
|
Self {
|
||||||
|
current_line: SpinLock::new(CurrentLine::new()),
|
||||||
|
read_buffer: SpinLock::new(StaticRb::default()),
|
||||||
|
foreground: SpinLock::new(Weak::new()),
|
||||||
|
termios: SpinLock::new(KernelTermios::default()),
|
||||||
|
winsize: SpinLock::new(WinSize::default()),
|
||||||
|
pollee: Pollee::new(IoEvents::empty()),
|
||||||
|
work_item,
|
||||||
|
work_item_para: Arc::new(SpinLock::new(LineDisciplineWorkPara::new())),
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push char to line discipline.
|
/// Push char to line discipline.
|
||||||
@ -157,17 +167,40 @@ impl LineDiscipline {
|
|||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
// FIXME: kernel_signal may sleep
|
// `kernel_signal()` may cause sleep, so only construct parameters here.
|
||||||
foreground.kernel_signal(signal);
|
self.work_item_para.lock_irq_disabled().kernel_signal = Some(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_readable_state(&self) {
|
fn update_readable_state(&self) {
|
||||||
let buffer = self.read_buffer.lock_irq_disabled();
|
let buffer = self.read_buffer.lock_irq_disabled();
|
||||||
// FIXME: add/del events may sleep
|
let pollee = self.pollee.clone();
|
||||||
|
// add/del events may sleep, so only construct parameters here.
|
||||||
if !buffer.is_empty() {
|
if !buffer.is_empty() {
|
||||||
self.pollee.add_events(IoEvents::IN);
|
self.work_item_para.lock_irq_disabled().pollee_type = Some(PolleeType::Add);
|
||||||
} else {
|
} else {
|
||||||
self.pollee.del_events(IoEvents::IN);
|
self.work_item_para.lock_irq_disabled().pollee_type = Some(PolleeType::Del);
|
||||||
|
}
|
||||||
|
submit_work_item(self.work_item.clone(), WorkPriority::High);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// include all operations that may cause sleep, and processes by a work queue.
|
||||||
|
fn update_readable_state_after(&self) {
|
||||||
|
if let Some(signal) = self.work_item_para.lock_irq_disabled().kernel_signal.take() {
|
||||||
|
self.foreground
|
||||||
|
.lock()
|
||||||
|
.upgrade()
|
||||||
|
.unwrap()
|
||||||
|
.kernel_signal(signal)
|
||||||
|
};
|
||||||
|
if let Some(pollee_type) = self.work_item_para.lock_irq_disabled().pollee_type.take() {
|
||||||
|
match pollee_type {
|
||||||
|
PolleeType::Add => {
|
||||||
|
self.pollee.add_events(IoEvents::IN);
|
||||||
|
}
|
||||||
|
PolleeType::Del => {
|
||||||
|
self.pollee.del_events(IoEvents::IN);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,3 +426,22 @@ fn meet_new_line(item: u8, termios: &KernelTermios) -> bool {
|
|||||||
fn should_not_be_read(item: u8, termios: &KernelTermios) -> bool {
|
fn should_not_be_read(item: u8, termios: &KernelTermios) -> bool {
|
||||||
item == *termios.get_special_char(CC_C_CHAR::VEOF)
|
item == *termios.get_special_char(CC_C_CHAR::VEOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PolleeType {
|
||||||
|
Add,
|
||||||
|
Del,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LineDisciplineWorkPara {
|
||||||
|
kernel_signal: Option<KernelSignal>,
|
||||||
|
pollee_type: Option<PolleeType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineDisciplineWorkPara {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
kernel_signal: None,
|
||||||
|
pollee_type: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@ pub struct Tty {
|
|||||||
/// tty_name
|
/// tty_name
|
||||||
name: CString,
|
name: CString,
|
||||||
/// line discipline
|
/// line discipline
|
||||||
ldisc: LineDiscipline,
|
ldisc: Arc<LineDiscipline>,
|
||||||
/// driver
|
/// driver
|
||||||
driver: SpinLock<Weak<TtyDriver>>,
|
driver: SpinLock<Weak<TtyDriver>>,
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user