完善Tty的RawMode (#577)

* 完善rowmode,改掉一部分bug

* 增加两个ansi拓展功能功能,以及标记部分函数nerve inline

* 修改do_signal和其他中断上下文锁未关中断,以及拓展tty功能,修改tty几个算法bug

* 修改两个锁

* 修改syscall_64

* update
This commit is contained in:
GnoCiYeH 2024-03-11 15:13:37 +08:00 committed by GitHub
parent 840045af94
commit 52bcb59e92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 561 additions and 290 deletions

View File

@ -327,6 +327,7 @@ ENTRY(ignore_int)
ENTRY(syscall_64) ENTRY(syscall_64)
// //
cli
swapgs swapgs
movq %rsp, %gs:0x8 movq %rsp, %gs:0x8
movq %gs:0x0, %rsp movq %gs:0x0, %rsp
@ -372,10 +373,12 @@ ENTRY(syscall_64)
movq %rsp, %rdi // rdi movq %rsp, %rdi // rdi
sti
callq *%rdx // callq *%rdx //
// do_signal // do_signal
movq %rsp, %rdi movq %rsp, %rdi
callq do_signal callq do_signal
cli cli

View File

@ -415,7 +415,8 @@ pub struct X86_64SignalArch;
impl SignalArch for X86_64SignalArch { impl SignalArch for X86_64SignalArch {
unsafe fn do_signal(frame: &mut TrapFrame) { unsafe fn do_signal(frame: &mut TrapFrame) {
let pcb = ProcessManager::current_pcb(); let pcb = ProcessManager::current_pcb();
let siginfo = pcb.try_siginfo(5);
let siginfo = pcb.try_siginfo_irqsave(5);
if unlikely(siginfo.is_none()) { if unlikely(siginfo.is_none()) {
return; return;
@ -437,7 +438,7 @@ impl SignalArch for X86_64SignalArch {
let sig_block: SigSet = siginfo_read_guard.sig_block().clone(); let sig_block: SigSet = siginfo_read_guard.sig_block().clone();
drop(siginfo_read_guard); drop(siginfo_read_guard);
let sig_guard = pcb.try_sig_struct_irq(5); let sig_guard = pcb.try_sig_struct_irqsave(5);
if unlikely(sig_guard.is_none()) { if unlikely(sig_guard.is_none()) {
return; return;
} }

View File

@ -140,12 +140,12 @@ bitflags! {
/// termios输入特性 /// termios输入特性
pub struct InputMode: u32 { pub struct InputMode: u32 {
/// 如果设置了该标志,表示启用软件流控制。 /// 如果设置了该标志,表示启用软件流控制。
const IXON = 0x0200; const IXON = 0x0400;
/// 如果设置了该标志,表示启用输入流控制。 /// 如果设置了该标志,表示启用输入流控制。
const IXOFF = 0x0400; const IXOFF = 0x1000;
/// Map Uppercase to Lowercase on Input 将大写转换为小写 /// Map Uppercase to Lowercase on Input 将大写转换为小写
/// 表示不区分大小写 /// 表示不区分大小写
const IUCLC = 0x1000; const IUCLC = 0x0200;
/// 如果设置了该标志,表示当输入队列满时,产生一个响铃信号。 /// 如果设置了该标志,表示当输入队列满时,产生一个响铃信号。
const IMAXBEL = 0x2000; const IMAXBEL = 0x2000;
/// 如果设置了该标志,表示输入数据被视为 UTF-8 编码。 /// 如果设置了该标志,表示输入数据被视为 UTF-8 编码。
@ -176,46 +176,44 @@ bitflags! {
/// termios输出特性 /// termios输出特性
pub struct OutputMode: u32 { pub struct OutputMode: u32 {
/// 在输出时将换行符替换\r\n /// 在输出时将换行符替换\r\n
const ONLCR = 0x00002; const ONLCR = 0x00004;
/// Map Lowercase to Uppercase on Output 输出字符时将小写字母映射为大写字母 /// Map Lowercase to Uppercase on Output 输出字符时将小写字母映射为大写字母
const OLCUC = 0x00004; const OLCUC = 0x00002;
/// 与NL协同 配置换行符的处理方式 /// 与NL协同 配置换行符的处理方式
const NLDLY = 0x00300; const NLDLY = 0x00100;
const NL0 = 0x00000; // 不延迟换行 const NL0 = 0x00000; // 不延迟换行
const NL1 = 0x00100; // 延迟换行(输出回车后等待一段时间再输出换行) const NL1 = 0x00100; // 延迟换行(输出回车后等待一段时间再输出换行)
const NL2 = 0x00200; // NL2 和 NL3保留暂未使用
const NL3 = 0x00300;
/// 配置水平制表符的处理方式 /// 配置水平制表符的处理方式
const TABDLY = 0x00c00; const TABDLY = 0x01800;
const TAB0 = 0x00000; // 不延迟水平制表符 const TAB0 = 0x00000; // 不延迟水平制表符
const TAB1 = 0x00400; // 在输出水平制表符时,延迟到下一个设置的水平制表符位置 const TAB1 = 0x00800; // 在输出水平制表符时,延迟到下一个设置的水平制表符位置
const TAB2 = 0x00800; // 在输出水平制表符时,延迟到下一个设置的 8 的倍数的位置 const TAB2 = 0x01000; // 在输出水平制表符时,延迟到下一个设置的 8 的倍数的位置
const TAB3 = 0x00c00; // TAB3 和 XTABS与 TAB3 等效)保留,暂未使用 const TAB3 = 0x01800; // TAB3 和 XTABS与 TAB3 等效)保留,暂未使用
const XTABS = 0x00c00; const XTABS = 0x01800;
/// 配置回车符的处理方式 /// 配置回车符的处理方式
const CRDLY = 0x03000; const CRDLY = 0x00600;
const CR0 = 0x00000; // 不延迟回车 const CR0 = 0x00000; // 不延迟回车
const CR1 = 0x01000; // 延迟回车(输出回车后等待一段时间再输出换行) const CR1 = 0x02000; // 延迟回车(输出回车后等待一段时间再输出换行)
const CR2 = 0x02000; // CR2 和 CR3保留暂未使用 const CR2 = 0x04000; // CR2 和 CR3保留暂未使用
const CR3 = 0x03000; const CR3 = 0x06000;
/// 配置换页符form feed的处理方式 /// 配置换页符form feed的处理方式
const FFDLY = 0x04000; const FFDLY = 0x08000;
const FF0 = 0x00000; // 不延迟换页 const FF0 = 0x00000; // 不延迟换页
const FF1 = 0x04000; // 延迟换页 const FF1 = 0x08000; // 延迟换页
/// 配置退格符backspace的处理方式 /// 配置退格符backspace的处理方式
const BSDLY = 0x08000; const BSDLY = 0x02000;
const BS0 = 0x00000; // 不延迟退格 const BS0 = 0x00000; // 不延迟退格
const BS1 = 0x08000; // 延迟退格 const BS1 = 0x02000; // 延迟退格
/// 配置垂直制表符vertical tab的处理方式 /// 配置垂直制表符vertical tab的处理方式
const VTDLY = 0x10000; const VTDLY = 0x04000;
const VT0 = 0x00000; // 不延迟垂直制表符 const VT0 = 0x00000; // 不延迟垂直制表符
const VT1 = 0x10000; // 延迟垂直制表符 const VT1 = 0x04000; // 延迟垂直制表符
/// 表示执行输出处理,即启用输出处理函数 /// 表示执行输出处理,即启用输出处理函数
const OPOST = 0x01; const OPOST = 0x01;
@ -234,13 +232,14 @@ bitflags! {
/// 配置终端设备的基本特性和控制参数 /// 配置终端设备的基本特性和控制参数
pub struct ControlMode: u32 { pub struct ControlMode: u32 {
/// Baud Rate Mask 指定波特率的掩码 /// Baud Rate Mask 指定波特率的掩码
const CBAUD = 0x000000ff; const CBAUD = 0x0000100f;
/// Extra Baud Bits 指定更高的波特率位 /// Extra Baud Bits 指定更高的波特率位
const CBAUDEX = 0x00000000; const CBAUDEX = 0x00001000;
/// Custom Baud Rate 指定自定义波特率 如果设置了 BOTHER则通过以下位来设置自定义的波特率值 /// Custom Baud Rate 指定自定义波特率 如果设置了 BOTHER则通过以下位来设置自定义的波特率值
const BOTHER = 0x0000001f; const BOTHER = 0x00001000;
const B0 = 0x00000000; /* Common CBAUD rates */
const B0 = 0x00000000; /* hang up */
const B50 = 0x00000001; const B50 = 0x00000001;
const B75 = 0x00000002; const B75 = 0x00000002;
const B110 = 0x00000003; const B110 = 0x00000003;
@ -257,43 +256,43 @@ bitflags! {
const B19200 = 0x0000000e; const B19200 = 0x0000000e;
const B38400 = 0x0000000f; const B38400 = 0x0000000f;
const B57600 = 0x00000010; const B57600 = 0x00001001;
const B115200 = 0x00000011; const B115200 = 0x00001002;
const B230400 = 0x00000012; const B230400 = 0x00001003;
const B460800 = 0x00000013; const B460800 = 0x00001004;
const B500000 = 0x00000014; const B500000 = 0x00001005;
const B576000 = 0x00000015; const B576000 = 0x00001006;
const B921600 = 0x00000016; const B921600 = 0x00001007;
const B1000000 = 0x00000017; const B1000000 = 0x00001008;
const B1152000 = 0x00000018; const B1152000 = 0x00001009;
const B1500000 = 0x00000019; const B1500000 = 0x0000100a;
const B2000000 = 0x0000001a; const B2000000 = 0x0000100b;
const B2500000 = 0x0000001b; const B2500000 = 0x0000100c;
const B3000000 = 0x0000001c; const B3000000 = 0x0000100d;
const B3500000 = 0x0000001d; const B3500000 = 0x0000100e;
const B4000000 = 0x0000001e; const B4000000 = 0x0000100f;
/// 指定字符大小的掩码 以下位为特定字符大小 /// 指定字符大小的掩码 以下位为特定字符大小
const CSIZE = 0x00000300; const CSIZE = 0x00000030;
const CS5 = 0x00000000; const CS5 = 0x00000000;
const CS6 = 0x00000100; const CS6 = 0x00000010;
const CS7 = 0x00000200; const CS7 = 0x00000020;
const CS8 = 0x00000300; const CS8 = 0x00000030;
/// Stop Bit Select 表示使用两个停止位;否则,表示使用一个停止位 /// Stop Bit Select 表示使用两个停止位;否则,表示使用一个停止位
const CSTOPB = 0x00000400; const CSTOPB = 0x00000040;
/// 表示启用接收器。如果未设置,则禁用接收器。 /// 表示启用接收器。如果未设置,则禁用接收器。
const CREAD = 0x00000800; const CREAD = 0x00000080;
/// 表示启用奇偶校验。如果未设置,则禁用奇偶校验。 /// 表示启用奇偶校验。如果未设置,则禁用奇偶校验。
const PARENB = 0x00001000; const PARENB = 0x00000100;
/// 表示启用奇校验。如果未设置,则表示启用偶校验。 /// 表示启用奇校验。如果未设置,则表示启用偶校验。
const PARODD = 0x00002000; const PARODD = 0x00000200;
/// 表示在终端设备被关闭时挂断线路(执行挂断操作) /// 表示在终端设备被关闭时挂断线路(执行挂断操作)
const HUPCL = 0x00004000; const HUPCL = 0x00000400;
/// 表示忽略调制解调器的状态DCD、DSR、CTS 等) /// 表示忽略调制解调器的状态DCD、DSR、CTS 等)
const CLOCAL = 0x00008000; const CLOCAL = 0x00000800;
/// 指定输入波特率的掩码 /// 指定输入波特率的掩码
const CIBAUD = 0x00ff0000; const CIBAUD = 0x100f0000;
const ADDRB = 0x20000000; const ADDRB = 0x20000000;
} }
@ -301,37 +300,37 @@ bitflags! {
/// 配置终端设备的本地模式local mode或控制输入处理的行为 /// 配置终端设备的本地模式local mode或控制输入处理的行为
pub struct LocalMode: u32 { pub struct LocalMode: u32 {
/// 启用中断字符Ctrl-C、Ctrl-Z /// 启用中断字符Ctrl-C、Ctrl-Z
const ISIG = 0x00000080; const ISIG = 0x00001;
/// 表示启用规范模式,即启用行缓冲和回显。在规范模式下,输入被缓冲,并且只有在输入回车符时才会传递给应用程序。 /// 表示启用规范模式,即启用行缓冲和回显。在规范模式下,输入被缓冲,并且只有在输入回车符时才会传递给应用程序。
const ICANON = 0x00000100; const ICANON = 0x00002;
/// 表示启用大写模式,即输入输出都将被转换为大写。 /// 表示启用大写模式,即输入输出都将被转换为大写。
const XCASE = 0x00004000; const XCASE = 0x00004;
/// 表示启用回显(显示用户输入的字符) /// 表示启用回显(显示用户输入的字符)
const ECHO = 0x00000008; const ECHO = 0x00008;
/// 表示在回显时将擦除的字符用 backspace 和空格字符显示。 /// 表示在回显时将擦除的字符用 backspace 和空格字符显示。
const ECHOE = 0x00000002; const ECHOE = 0x00010;
/// 表示在回显时将换行符后的字符用空格字符显示。 /// 表示在回显时将换行符后的字符用空格字符显示。
const ECHOK = 0x00000004; const ECHOK = 0x00020;
/// 表示在回显时将换行符显示为换行和回车符。 /// 表示在回显时将换行符显示为换行和回车符。
const ECHONL = 0x00000010; const ECHONL = 0x00040;
/// 表示在收到中断Ctrl-C和退出Ctrl-\)字符后,不清空输入和输出缓冲区。 /// 表示在收到中断Ctrl-C和退出Ctrl-\)字符后,不清空输入和输出缓冲区。
const NOFLSH = 0x80000000; const NOFLSH = 0x00080;
/// 表示在后台进程尝试写入终端时发送停止信号Ctrl-S /// 表示在后台进程尝试写入终端时发送停止信号Ctrl-S
const TOSTOP = 0x00400000; const TOSTOP = 0x00100;
/// 表示在回显时,显示控制字符为 ^ 加字符。 /// 表示在回显时,显示控制字符为 ^ 加字符。
const ECHOCTL= 0x00000040; const ECHOCTL= 0x00200;
/// 表示在回显时显示带有 # 的换行符(为了与 echo -n 命令兼容)。 /// 表示在回显时显示带有 # 的换行符(为了与 echo -n 命令兼容)。
const ECHOPRT= 0x00000020; const ECHOPRT= 0x00400;
/// 表示在回显时将 KILL 字符Ctrl-U用空格字符显示。 /// 表示在回显时将 KILL 字符Ctrl-U用空格字符显示。
const ECHOKE = 0x00000001; const ECHOKE = 0x00800;
/// 表示输出正在被冲刷flush通常是由于输入/输出流的状态变化。 /// 表示输出正在被冲刷flush通常是由于输入/输出流的状态变化。
const FLUSHO = 0x00800000; const FLUSHO = 0x01000;
/// 表示在规范模式下,存在需要重新打印的字符。 /// 表示在规范模式下,存在需要重新打印的字符。
const PENDIN = 0x20000000; const PENDIN = 0x04000;
/// 表示启用实现定义的输入处理。 /// 表示启用实现定义的输入处理。
const IEXTEN = 0x00000400; const IEXTEN = 0x08000;
/// 表示启用扩展的处理函数 /// 表示启用扩展的处理函数
const EXTPROC= 0x10000000; const EXTPROC= 0x10000;
} }
pub struct TtySetTermiosOpt: u8 { pub struct TtySetTermiosOpt: u8 {

View File

@ -1,6 +1,6 @@
use core::{fmt::Debug, sync::atomic::AtomicBool}; use core::{fmt::Debug, sync::atomic::AtomicBool};
use alloc::{string::String, sync::Arc, vec::Vec}; use alloc::{collections::LinkedList, string::String, sync::Arc, vec::Vec};
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::{
@ -11,7 +11,7 @@ use crate::{
wait_queue::EventWaitQueue, wait_queue::EventWaitQueue,
}, },
mm::VirtAddr, mm::VirtAddr,
net::event_poll::EPollEventType, net::event_poll::{EPollEventType, EPollItem},
process::Pid, process::Pid,
syscall::user_access::{UserBufferReader, UserBufferWriter}, syscall::user_access::{UserBufferReader, UserBufferWriter},
}; };
@ -53,6 +53,7 @@ impl TtyCore {
closing: AtomicBool::new(false), closing: AtomicBool::new(false),
flow: SpinLock::new(TtyFlowState::default()), flow: SpinLock::new(TtyFlowState::default()),
link: None, link: None,
epitems: SpinLock::new(LinkedList::new()),
}; };
return Arc::new(Self { return Arc::new(Self {
@ -159,6 +160,13 @@ impl TtyCore {
user_writer.copy_one_to_user(&termios, 0)?; user_writer.copy_one_to_user(&termios, 0)?;
return Ok(0); return Ok(0);
} }
TtyIoctlCmd::TCSETS => {
return TtyCore::core_set_termios(
real_tty,
VirtAddr::new(arg),
TtySetTermiosOpt::TERMIOS_OLD,
);
}
TtyIoctlCmd::TCSETSW => { TtyIoctlCmd::TCSETSW => {
return TtyCore::core_set_termios( return TtyCore::core_set_termios(
real_tty, real_tty,
@ -213,9 +221,7 @@ impl TtyCore {
let mut termios = tty.core().termios_write(); let mut termios = tty.core().termios_write();
let old_termios = termios.clone(); let old_termios = termios.clone();
*termios = new_termios; *termios = new_termios;
let tmp = termios.control_mode; let tmp = termios.control_mode;
termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB; termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
@ -300,6 +306,8 @@ pub struct TtyCoreData {
flow: SpinLock<TtyFlowState>, flow: SpinLock<TtyFlowState>,
/// 链接tty /// 链接tty
link: Option<Arc<TtyCore>>, link: Option<Arc<TtyCore>>,
/// epitems
epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
} }
impl TtyCoreData { impl TtyCoreData {
@ -335,17 +343,17 @@ impl TtyCoreData {
#[inline] #[inline]
pub fn termios(&self) -> RwLockReadGuard<'_, Termios> { pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
self.termios.read() self.termios.read_irqsave()
} }
#[inline] #[inline]
pub fn termios_write(&self) -> RwLockWriteGuard<Termios> { pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
self.termios.write() self.termios.write_irqsave()
} }
#[inline] #[inline]
pub fn set_termios(&self, termios: Termios) { pub fn set_termios(&self, termios: Termios) {
let mut termios_guard = self.termios.write(); let mut termios_guard = self.termios.write_irqsave();
*termios_guard = termios; *termios_guard = termios;
} }
@ -394,6 +402,11 @@ impl TtyCoreData {
pub fn link(&self) -> Option<Arc<TtyCore>> { pub fn link(&self) -> Option<Arc<TtyCore>> {
self.link.clone() self.link.clone()
} }
#[inline]
pub fn add_epitem(&self, epitem: Arc<EPollItem>) {
self.epitems.lock().push_back(epitem)
}
} }
/// TTY 核心接口不同的tty需要各自实现这个trait /// TTY 核心接口不同的tty需要各自实现这个trait

View File

@ -30,8 +30,9 @@ use crate::{
init::initcall::INITCALL_DEVICE, init::initcall::INITCALL_DEVICE,
libs::rwlock::RwLock, libs::rwlock::RwLock,
mm::VirtAddr, mm::VirtAddr,
net::event_poll::{EPollItem, EventPoll},
process::ProcessManager, process::ProcessManager,
syscall::user_access::UserBufferWriter, syscall::user_access::{UserBufferReader, UserBufferWriter},
}; };
use super::{ use super::{
@ -131,7 +132,7 @@ impl IndexNode for TtyDevice {
&& driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster)) && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
{ {
let pcb = ProcessManager::current_pcb(); let pcb = ProcessManager::current_pcb();
let pcb_tty = pcb.sig_info().tty(); let pcb_tty = pcb.sig_info_irqsave().tty();
if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() { if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
TtyJobCtrlManager::proc_set_tty(tty); TtyJobCtrlManager::proc_set_tty(tty);
} }
@ -210,7 +211,7 @@ impl IndexNode for TtyDevice {
// 将数据从buf拷贝到writebuf // 将数据从buf拷贝到writebuf
let ret = ld.write(tty.clone(), buf, size, mode)?; let ret = ld.write(tty.clone(), &buf[written..], size, mode)?;
written += ret; written += ret;
count -= ret; count -= ret;
@ -219,7 +220,7 @@ impl IndexNode for TtyDevice {
break; break;
} }
if pcb.sig_info().sig_pending().has_pending() { if pcb.sig_info_irqsave().sig_pending().has_pending() {
return Err(SystemError::ERESTARTSYS); return Err(SystemError::ERESTARTSYS);
} }
} }
@ -273,6 +274,20 @@ impl IndexNode for TtyDevice {
todo!() todo!()
} }
} }
EventPoll::ADD_EPOLLITEM => {
let _ = UserBufferReader::new(
arg as *const Arc<EPollItem>,
core::mem::size_of::<Arc<EPollItem>>(),
false,
)?;
let epitem = unsafe { &*(arg as *const Arc<EPollItem>) };
let core = tty.core();
core.add_epitem(epitem.clone());
return Ok(0);
}
_ => {} _ => {}
} }
@ -319,6 +334,16 @@ impl IndexNode for TtyDevice {
Ok(0) Ok(0)
} }
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
(tty_priv.tty.clone(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
tty.ldisc().poll(tty)
}
} }
impl DeviceINode for TtyDevice { impl DeviceINode for TtyDevice {

View File

@ -34,7 +34,9 @@ impl TtyJobCtrlManager {
pub fn tty_check_change(tty: Arc<TtyCore>, sig: Signal) -> Result<(), SystemError> { pub fn tty_check_change(tty: Arc<TtyCore>, sig: Signal) -> Result<(), SystemError> {
let pcb = ProcessManager::current_pcb(); let pcb = ProcessManager::current_pcb();
if pcb.sig_info().tty().is_none() || !Arc::ptr_eq(&pcb.sig_info().tty().unwrap(), &tty) { if pcb.sig_info_irqsave().tty().is_none()
|| !Arc::ptr_eq(&pcb.sig_info_irqsave().tty().unwrap(), &tty)
{
return Ok(()); return Ok(());
} }
@ -91,8 +93,8 @@ impl TtyJobCtrlManager {
let mut ctrl = tty.core().contorl_info_irqsave(); let mut ctrl = tty.core().contorl_info_irqsave();
if current.sig_info().tty().is_none() if current.sig_info_irqsave().tty().is_none()
|| !Arc::ptr_eq(&current.sig_info().tty().clone().unwrap(), &tty) || !Arc::ptr_eq(&current.sig_info_irqsave().tty().clone().unwrap(), &tty)
|| ctrl.session.is_none() || ctrl.session.is_none()
|| ctrl.session.unwrap() != current.pid() || ctrl.session.unwrap() != current.pid()
{ {
@ -106,8 +108,8 @@ impl TtyJobCtrlManager {
TtyIoctlCmd::TIOCGPGRP => { TtyIoctlCmd::TIOCGPGRP => {
let current = ProcessManager::current_pcb(); let current = ProcessManager::current_pcb();
if current.sig_info().tty().is_some() if current.sig_info_irqsave().tty().is_some()
&& !Arc::ptr_eq(&current.sig_info().tty().unwrap(), &tty) && !Arc::ptr_eq(&current.sig_info_irqsave().tty().unwrap(), &tty)
{ {
return Err(SystemError::ENOTTY); return Err(SystemError::ENOTTY);
} }

View File

@ -48,7 +48,7 @@ pub trait TtyLineDiscipline: Sync + Send + Debug {
/// - old: 之前的termios如果为None则表示第一次设置 /// - old: 之前的termios如果为None则表示第一次设置
fn set_termios(&self, tty: Arc<TtyCore>, old: Option<Termios>) -> Result<(), SystemError>; fn set_termios(&self, tty: Arc<TtyCore>, old: Option<Termios>) -> Result<(), SystemError>;
fn poll(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, SystemError>;
fn hangup(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; fn hangup(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
/// ## 接收数据 /// ## 接收数据

View File

@ -1,3 +1,4 @@
use core::intrinsics::likely;
use core::ops::BitXor; use core::ops::BitXor;
use bitmap::{traits::BitMapOps, StaticBitmap}; use bitmap::{traits::BitMapOps, StaticBitmap};
@ -249,11 +250,10 @@ impl NTtyData {
|| termios.local_mode.contains(LocalMode::IEXTEN); || termios.local_mode.contains(LocalMode::IEXTEN);
let look_ahead = self.lookahead_count.min(count); let look_ahead = self.lookahead_count.min(count);
if self.real_raw { if self.real_raw {
todo!("tty real raw mode todo"); self.receive_buf_real_raw(buf, count);
} else if self.raw || (termios.local_mode.contains(LocalMode::EXTPROC) && !preops) { } else if self.raw || (termios.local_mode.contains(LocalMode::EXTPROC) && !preops) {
todo!("tty raw mode todo"); self.receive_buf_raw(buf, flags, count);
} else if tty.core().is_closing() && !termios.local_mode.contains(LocalMode::EXTPROC) { } else if tty.core().is_closing() && !termios.local_mode.contains(LocalMode::EXTPROC) {
todo!() todo!()
} else { } else {
@ -282,7 +282,47 @@ impl NTtyData {
if self.read_cnt() > 0 { if self.read_cnt() > 0 {
tty.core() tty.core()
.read_wq() .read_wq()
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDBAND).bits() as u64); .wakeup_any((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDBAND).bits() as u64);
}
}
fn receive_buf_real_raw(&mut self, buf: &[u8], mut count: usize) {
let mut head = ntty_buf_mask(self.read_head);
let mut n = count.min(NTTY_BUFSIZE - head);
// 假如有一部分在队列头部,则这部分是拷贝尾部部分
self.read_buf[head..(head + n)].copy_from_slice(&buf[0..n]);
self.read_head += n;
count -= n;
let offset = n;
// 假如有一部分在队列头部,则这部分是拷贝头部部分
head = ntty_buf_mask(self.read_head);
n = count.min(NTTY_BUFSIZE - head);
self.read_buf[head..(head + n)].copy_from_slice(&buf[offset..(offset + n)]);
self.read_head += n;
}
fn receive_buf_raw(&mut self, buf: &[u8], flags: Option<&[u8]>, mut count: usize) {
// TTY_NORMAL 目前这部分未做,所以先占位置而不做抽象
let mut flag = 1;
let mut f_offset = 0;
let mut c_offset = 0;
while count != 0 {
if flags.is_some() {
flag = flags.as_ref().unwrap()[f_offset];
f_offset += 1;
}
if likely(flag == 1) {
self.read_buf[self.read_head] = buf[c_offset];
c_offset += 1;
self.read_head += 1;
} else {
todo!()
}
count -= 1;
} }
} }
@ -364,6 +404,7 @@ impl NTtyData {
} }
} }
#[inline(never)]
pub fn receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool) { pub fn receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool) {
let is_flow_ctrl = self.is_flow_ctrl_char(tty.clone(), c, lookahead_done); let is_flow_ctrl = self.is_flow_ctrl_char(tty.clone(), c, lookahead_done);
let termios = tty.core().termios(); let termios = tty.core().termios();
@ -467,9 +508,9 @@ impl NTtyData {
self.read_buf[ntty_buf_mask(self.read_head)] = c; self.read_buf[ntty_buf_mask(self.read_head)] = c;
self.read_head += 1; self.read_head += 1;
self.canon_head = self.read_head; self.canon_head = self.read_head;
tty.core() tty.core().read_wq().wakeup_any(
.read_wq() (EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64); );
return; return;
} }
@ -480,9 +521,9 @@ impl NTtyData {
self.read_buf[ntty_buf_mask(self.read_head)] = c; self.read_buf[ntty_buf_mask(self.read_head)] = c;
self.read_head += 1; self.read_head += 1;
self.canon_head = self.read_head; self.canon_head = self.read_head;
tty.core() tty.core().read_wq().wakeup_any(
.read_wq() (EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64); );
return; return;
} }
@ -508,9 +549,9 @@ impl NTtyData {
self.read_buf[ntty_buf_mask(self.read_head)] = c; self.read_buf[ntty_buf_mask(self.read_head)] = c;
self.read_head += 1; self.read_head += 1;
self.canon_head = self.read_head; self.canon_head = self.read_head;
tty.core() tty.core().read_wq().wakeup_any(
.read_wq() (EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
.wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64); );
return; return;
} }
} }
@ -540,6 +581,7 @@ impl NTtyData {
} }
/// ## ntty默认eraser function /// ## ntty默认eraser function
#[inline(never)]
fn eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>) { fn eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>) {
if self.read_head == self.canon_head { if self.read_head == self.canon_head {
return; return;
@ -907,7 +949,7 @@ impl NTtyData {
// 有一部分数据在头部,则先拷贝后面部分,再拷贝头部 // 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
// TODO: tty审计 // TODO: tty审计
to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]); to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
to[size..].copy_from_slice(&self.read_buf[(tail + size)..(*n + tail)]); to[size..(*n)].copy_from_slice(&self.read_buf[0..(*n - size)]);
} else { } else {
to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)]) to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
} }
@ -975,7 +1017,7 @@ impl NTtyData {
let size = if tail + n > NTTY_BUFSIZE { let size = if tail + n > NTTY_BUFSIZE {
NTTY_BUFSIZE NTTY_BUFSIZE
} else { } else {
tail + *nr tail + n
}; };
// 找到eol的坐标 // 找到eol的坐标
@ -1088,7 +1130,7 @@ impl NTtyData {
let tail = self.read_tail & (NTTY_BUFSIZE - 1); let tail = self.read_tail & (NTTY_BUFSIZE - 1);
// 计算出可读的字符数 // 计算出可读的字符数
let mut n = (NTTY_BUFSIZE - tail).min(self.read_tail); let mut n = (NTTY_BUFSIZE - tail).min(head - self.read_tail);
n = n.min(*nr); n = n.min(*nr);
if n > 0 { if n > 0 {
@ -1209,6 +1251,7 @@ impl NTtyData {
} }
} }
#[inline(never)]
pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> { pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> {
let mut space = tty.write_room(tty.core()); let mut space = tty.write_room(tty.core());
let ospace = space; let ospace = space;
@ -1519,6 +1562,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
Ok(()) Ok(())
} }
#[inline(never)]
fn read( fn read(
&self, &self,
tty: Arc<TtyCore>, tty: Arc<TtyCore>,
@ -1555,7 +1599,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
return Ok(len - nr); return Ok(len - nr);
} }
} else { } else {
if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? { if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? {
return Ok(len - nr); return Ok(len - nr);
} }
} }
@ -1610,7 +1654,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
} }
if ProcessManager::current_pcb() if ProcessManager::current_pcb()
.sig_info() .sig_info_irqsave()
.sig_pending() .sig_pending()
.has_pending() .has_pending()
{ {
@ -1666,6 +1710,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
ret ret
} }
#[inline(never)]
fn write( fn write(
&self, &self,
tty: Arc<TtyCore>, tty: Arc<TtyCore>,
@ -1687,7 +1732,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
// drop(ldata); // drop(ldata);
let mut offset = 0; let mut offset = 0;
loop { loop {
if pcb.sig_info().sig_pending().has_pending() { if pcb.sig_info_irqsave().sig_pending().has_pending() {
return Err(SystemError::ERESTARTSYS); return Err(SystemError::ERESTARTSYS);
} }
if core.flags().contains(TtyFlag::HUPPED) { if core.flags().contains(TtyFlag::HUPPED) {
@ -1818,6 +1863,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
} }
} }
#[inline(never)]
fn set_termios( fn set_termios(
&self, &self,
tty: Arc<TtyCore>, tty: Arc<TtyCore>,
@ -1829,14 +1875,13 @@ impl TtyLineDiscipline for NTtyLinediscipline {
let contorl_chars = termios.control_characters; let contorl_chars = termios.control_characters;
// 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化 // 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
if old.is_none() let mut spec_mode_changed = false;
|| (old.is_some() if old.is_some() {
&& old let local_mode = old.clone().unwrap().local_mode.bitxor(termios.local_mode);
.unwrap() spec_mode_changed =
.local_mode local_mode.contains(LocalMode::ICANON) || local_mode.contains(LocalMode::EXTPROC);
.bitxor(termios.local_mode) }
.contains(LocalMode::ICANON | LocalMode::EXTPROC)) if old.is_none() || spec_mode_changed {
{
// 重置read_flags // 重置read_flags
ldata.read_flags.set_all(false); ldata.read_flags.set_all(false);
@ -1859,10 +1904,8 @@ impl TtyLineDiscipline for NTtyLinediscipline {
ldata.lnext = false; ldata.lnext = false;
} }
// 设置规范模式 // 设置模式
if termios.local_mode.contains(LocalMode::ICANON) { ldata.icanon = termios.local_mode.contains(LocalMode::ICANON);
ldata.icanon = true;
}
// 设置回显 // 设置回显
if termios.local_mode.contains(LocalMode::ECHO) { if termios.local_mode.contains(LocalMode::ECHO) {
@ -1984,8 +2027,37 @@ impl TtyLineDiscipline for NTtyLinediscipline {
Ok(()) Ok(())
} }
fn poll(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError> {
todo!() let core = tty.core();
let ldata = self.disc_data();
let mut event = EPollEventType::empty();
if ldata.input_available(core.termios(), true) {
event.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM)
}
if core.contorl_info_irqsave().packet {
let link = core.link();
if link.is_some() && link.unwrap().core().contorl_info_irqsave().pktstatus != 0 {
event.insert(
EPollEventType::EPOLLPRI
| EPollEventType::EPOLLIN
| EPollEventType::EPOLLRDNORM,
);
}
}
if core.flags().contains(TtyFlag::OTHER_CLOSED) {
event.insert(EPollEventType::EPOLLHUP);
}
if core.driver().driver_funcs().chars_in_buffer() < 256
&& core.driver().driver_funcs().write_room(core) > 0
{
event.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
}
Ok(event.bits() as usize)
} }
fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {

View File

@ -102,62 +102,8 @@ impl TtyConsoleDriverInner {
console: Arc::new(BlittingFbConsole::new()?), console: Arc::new(BlittingFbConsole::new()?),
}) })
} }
}
impl TtyOperation for TtyConsoleDriverInner { fn do_write(&self, tty: &TtyCoreData, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
fn install(&self, _driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
let tty_core = tty.core();
let mut vc_data = VIRT_CONSOLES[tty_core.index()].lock();
self.console.con_init(&mut vc_data, true)?;
if vc_data.complement_mask == 0 {
vc_data.complement_mask = if vc_data.color_mode { 0x7700 } else { 0x0800 };
}
vc_data.s_complement_mask = vc_data.complement_mask;
// vc_data.bytes_per_row = vc_data.cols << 1;
vc_data.index = tty_core.index();
vc_data.bottom = vc_data.rows;
vc_data.set_driver_funcs(Arc::downgrade(
&(self.console.clone() as Arc<dyn ConsoleSwitch>),
));
// todo: unicode字符集处理
if vc_data.cols > VC_MAXCOL || vc_data.rows > VC_MAXROW {
return Err(SystemError::EINVAL);
}
vc_data.init(None, None, true);
vc_data.update_attr();
let window_size = tty_core.window_size_upgradeable();
if window_size.col == 0 && window_size.row == 0 {
let mut window_size = window_size.upgrade();
window_size.col = vc_data.cols as u16;
window_size.row = vc_data.rows as u16;
}
if vc_data.utf {
tty_core.termios_write().input_mode.insert(InputMode::IUTF8);
} else {
tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
}
// 加入sysfs
Ok(())
}
fn open(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
Ok(())
}
fn write_room(&self, _tty: &TtyCoreData) -> usize {
32768
}
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894
fn write(&self, tty: &TtyCoreData, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
// 关闭中断 // 关闭中断
let mut vc_data = tty.vc_data_irqsave(); let mut vc_data = tty.vc_data_irqsave();
@ -204,7 +150,70 @@ impl TtyOperation for TtyConsoleDriverInner {
// TODO: notify update // TODO: notify update
return Ok(offset); return Ok(offset);
} }
}
impl TtyOperation for TtyConsoleDriverInner {
fn install(&self, _driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
let tty_core = tty.core();
let mut vc_data = VIRT_CONSOLES[tty_core.index()].lock();
self.console.con_init(&mut vc_data, true)?;
if vc_data.complement_mask == 0 {
vc_data.complement_mask = if vc_data.color_mode { 0x7700 } else { 0x0800 };
}
vc_data.s_complement_mask = vc_data.complement_mask;
// vc_data.bytes_per_row = vc_data.cols << 1;
vc_data.index = tty_core.index();
vc_data.bottom = vc_data.rows;
vc_data.set_driver_funcs(Arc::downgrade(
&(self.console.clone() as Arc<dyn ConsoleSwitch>),
));
// todo: unicode字符集处理
if vc_data.cols > VC_MAXCOL || vc_data.rows > VC_MAXROW {
return Err(SystemError::EINVAL);
}
vc_data.init(None, None, true);
vc_data.update_attr();
let window_size = tty_core.window_size_upgradeable();
if window_size.col == 0 && window_size.row == 0 {
let mut window_size = window_size.upgrade();
window_size.col = vc_data.cols as u16;
window_size.row = vc_data.rows as u16;
kerror!("window_size {:?}", *window_size);
}
if vc_data.utf {
tty_core.termios_write().input_mode.insert(InputMode::IUTF8);
} else {
tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
}
// 加入sysfs
Ok(())
}
fn open(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
Ok(())
}
fn write_room(&self, _tty: &TtyCoreData) -> usize {
32768
}
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894
#[inline(never)]
fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
let ret = self.do_write(tty, buf, nr);
self.flush_chars(tty);
ret
}
#[inline(never)]
fn flush_chars(&self, tty: &TtyCoreData) { fn flush_chars(&self, tty: &TtyCoreData) {
let mut vc_data = tty.vc_data_irqsave(); let mut vc_data = tty.vc_data_irqsave();
vc_data.set_cursor(); vc_data.set_cursor();

View File

@ -7,7 +7,10 @@ use alloc::{
use bitmap::{traits::BitMapOps, StaticBitmap}; use bitmap::{traits::BitMapOps, StaticBitmap};
use crate::{ use crate::{
driver::tty::{console::ConsoleSwitch, ConsoleFont, KDMode}, driver::{
serial::serial8250::send_to_default_serial8250_port,
tty::{console::ConsoleSwitch, ConsoleFont, KDMode},
},
libs::{font::FontDesc, rwlock::RwLock}, libs::{font::FontDesc, rwlock::RwLock},
process::Pid, process::Pid,
}; };
@ -140,6 +143,7 @@ pub struct VirtualConsoleData {
} }
impl VirtualConsoleData { impl VirtualConsoleData {
#[inline(never)]
pub fn new(num: usize) -> Self { pub fn new(num: usize) -> Self {
Self { Self {
state: VirtualConsoleInfo::new(0, 0), state: VirtualConsoleInfo::new(0, 0),
@ -264,7 +268,8 @@ impl VirtualConsoleData {
self.pid = None; self.pid = None;
self.vc_state = VirtualConsoleState::ESnormal; self.vc_state = VirtualConsoleState::ESnormal;
self.reset_palette(); self.reset_palette();
self.cursor_type = VcCursor::CUR_UNDERLINE; // self.cursor_type = VcCursor::CUR_UNDERLINE;
self.cursor_type = VcCursor::CUR_BLOCK;
self.default_attr(); self.default_attr();
self.update_attr(); self.update_attr();
@ -567,10 +572,10 @@ impl VirtualConsoleData {
let min_y; let min_y;
if self.origin_mode { if self.origin_mode {
min_y = self.top; min_y = self.top;
max_y = self.bottom; max_y = self.bottom - 1;
} else { } else {
min_y = 0; min_y = 0;
max_y = self.rows; max_y = self.rows - 1;
} }
if y < min_y as i32 { if y < min_y as i32 {
@ -596,9 +601,10 @@ impl VirtualConsoleData {
return; return;
} }
if self if self.is_visible()
.driver_funcs() && self
.con_scroll(self, self.top, self.bottom, dir, nr) .driver_funcs()
.con_scroll(self, self.top, self.bottom, dir, nr)
{ {
// 如果成功 // 如果成功
return; return;
@ -733,6 +739,7 @@ impl VirtualConsoleData {
} }
} }
#[inline(never)]
fn do_getpars(&mut self, c: char) { fn do_getpars(&mut self, c: char) {
if c == ';' && self.npar < (NPAR - 1) as u32 { if c == ';' && self.npar < (NPAR - 1) as u32 {
self.npar += 1; self.npar += 1;
@ -789,9 +796,11 @@ impl VirtualConsoleData {
'n' => { 'n' => {
if self.private == Vt102_OP::EPecma { if self.private == Vt102_OP::EPecma {
if self.par[0] == 5 { if self.par[0] == 5 {
kwarn!("tty status report todo"); send_to_default_serial8250_port("tty status report todo".as_bytes());
panic!();
} else if self.par[0] == 6 { } else if self.par[0] == 6 {
kwarn!("tty cursor report todo"); send_to_default_serial8250_port("tty cursor report todo".as_bytes());
panic!();
} }
} }
return; return;
@ -847,7 +856,7 @@ impl VirtualConsoleData {
self.par[0] += 1; self.par[0] += 1;
} }
self.gotoxy( self.gotoxy(
(self.state.x - self.par[0] as usize) as i32, self.state.x as i32 - self.par[0] as i32,
self.state.y as i32, self.state.y as i32,
); );
return; return;
@ -863,7 +872,7 @@ impl VirtualConsoleData {
if self.par[0] == 0 { if self.par[0] == 0 {
self.par[0] += 1; self.par[0] += 1;
} }
self.gotoxy(0, (self.state.y - self.par[0] as usize) as i32); self.gotoxy(0, self.state.y as i32 - self.par[0] as i32);
return; return;
} }
'd' => { 'd' => {
@ -874,6 +883,7 @@ impl VirtualConsoleData {
return; return;
} }
'H' | 'f' => { 'H' | 'f' => {
// MOVETO
if self.par[0] != 0 { if self.par[0] != 0 {
self.par[0] -= 1; self.par[0] -= 1;
} }
@ -900,6 +910,18 @@ impl VirtualConsoleData {
'P' => { 'P' => {
todo!("csi_P todo"); todo!("csi_P todo");
} }
// 非ANSI标准为ANSI拓展
'S' => {
self.scroll(ScrollDir::Up, self.par[0] as usize);
return;
}
'T' => {
self.scroll(ScrollDir::Down, self.par[0] as usize);
return;
}
'c' => { 'c' => {
if self.par[0] == 0 { if self.par[0] == 0 {
kwarn!("respone ID todo"); kwarn!("respone ID todo");
@ -957,6 +979,7 @@ impl VirtualConsoleData {
} }
/// ## 处理Control Sequence Introducer控制序列引导符 m字符 /// ## 处理Control Sequence Introducer控制序列引导符 m字符
#[inline(never)]
fn csi_m(&mut self) { fn csi_m(&mut self) {
let mut i = 0; let mut i = 0;
loop { loop {
@ -1236,6 +1259,7 @@ impl VirtualConsoleData {
} }
/// ## 处理终端控制字符 /// ## 处理终端控制字符
#[inline(never)]
pub(super) fn do_control(&mut self, ch: u32) { pub(super) fn do_control(&mut self, ch: u32) {
// 首先检查是否处于 ANSI 控制字符串状态 // 首先检查是否处于 ANSI 控制字符串状态
if self.vc_state.is_ansi_control_string() && ch >= 8 && ch <= 13 { if self.vc_state.is_ansi_control_string() && ch >= 8 && ch <= 13 {
@ -1512,6 +1536,7 @@ impl VirtualConsoleData {
} }
} }
#[inline(never)]
pub(super) fn console_write_normal( pub(super) fn console_write_normal(
&mut self, &mut self,
mut tc: u32, mut tc: u32,
@ -1641,11 +1666,10 @@ impl VirtualConsoleData {
fn do_update_region(&self, mut start: usize, mut count: usize) { fn do_update_region(&self, mut start: usize, mut count: usize) {
let ret = self.driver_funcs().con_getxy(self, start); let ret = self.driver_funcs().con_getxy(self, start);
let (mut x, mut y) = if ret.is_err() { let (mut x, mut y) = if ret.is_err() {
let offset = start / 2; (start % self.cols, start / self.cols)
(offset % self.cols, offset / self.cols)
} else { } else {
let (tmp_start, tmp_x, tmp_y) = ret.unwrap(); let (_, tmp_x, tmp_y) = ret.unwrap();
start = tmp_start; // start = tmp_start;
(tmp_x, tmp_y) (tmp_x, tmp_y)
}; };
@ -1697,6 +1721,8 @@ impl VirtualConsoleData {
let ret = self.driver_funcs().con_getxy(self, start); let ret = self.driver_funcs().con_getxy(self, start);
if ret.is_ok() { if ret.is_ok() {
start = ret.unwrap().0; start = ret.unwrap().0;
} else {
return;
} }
} }
} }

View File

@ -391,6 +391,7 @@ impl ConsoleSwitch for BlittingFbConsole {
Ok(()) Ok(())
} }
#[inline(never)]
fn con_scroll( fn con_scroll(
&self, &self,
vc_data: &mut VirtualConsoleData, vc_data: &mut VirtualConsoleData,
@ -504,7 +505,30 @@ impl ConsoleSwitch for BlittingFbConsole {
} }
match scroll_mode { match scroll_mode {
ScrollMode::Move => todo!(), ScrollMode::Move => {
let start = top * vc_data.cols;
let end = bottom * vc_data.cols;
vc_data.screen_buf[start..end].rotate_right(count * vc_data.cols);
let _ = self.bmove(
vc_data,
top as i32,
0,
top as i32 + count as i32,
0,
(bottom - top - count) as u32,
vc_data.cols as u32,
);
let _ = self.con_clear(vc_data, top, 0, count, vc_data.cols);
let offset = vc_data.cols * count;
for i in vc_data.screen_buf[start..(start + offset)].iter_mut() {
*i = vc_data.erase_char;
}
return true;
}
ScrollMode::PanMove => todo!(), ScrollMode::PanMove => todo!(),
ScrollMode::WrapMove => todo!(), ScrollMode::WrapMove => todo!(),
ScrollMode::Redraw => { ScrollMode::Redraw => {
@ -554,7 +578,8 @@ impl FrameBufferConsole for BlittingFbConsole {
sy * vc_data.font.height as i32, sy * vc_data.font.height as i32,
); );
self.fb().fb_copyarea(area) self.fb().fb_copyarea(area);
Ok(())
} }
fn clear( fn clear(

View File

@ -408,9 +408,7 @@ pub trait FrameBufferOps {
} }
/// 将数据从一处复制到另一处。 /// 将数据从一处复制到另一处。
fn fb_copyarea(&self, _data: CopyAreaData) -> Result<(), SystemError> { fn fb_copyarea(&self, _data: CopyAreaData);
Err(SystemError::ENOSYS)
}
/// 将帧缓冲区的内容映射到用户空间。 /// 将帧缓冲区的内容映射到用户空间。
fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> { fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {

View File

@ -418,86 +418,138 @@ impl FrameBufferOps for VesaFb {
Ok(()) Ok(())
} }
fn fb_copyarea(&self, data: super::base::CopyAreaData) -> Result<(), SystemError> { #[inline(never)]
fn fb_copyarea(&self, data: super::base::CopyAreaData) {
let bp = boot_params().read(); let bp = boot_params().read();
let base = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?; let base = bp.screen_info.lfb_virt_base.unwrap();
let var = self.current_fb_var(); let var = self.current_fb_var();
if data.sx < 0 // 原区域或者目标区域全在屏幕外,则直接返回
|| data.sy < 0 if data.sx > var.xres as i32
|| data.sx as u32 > var.xres || data.sy > var.yres as i32
|| data.sx as u32 + data.width > var.xres || data.dx > var.xres as i32
|| data.sy as u32 > var.yres || data.dy > var.yres as i32
|| data.sy as u32 + data.height > var.yres || (data.sx + data.width as i32) < 0
|| (data.sy + data.height as i32) < 0
|| (data.dx + data.width as i32) < 0
|| (data.dy + data.height as i32) < 0
{ {
return Err(SystemError::EINVAL); return;
} }
// 求两个矩形可视范围交集
let (s_visiable_x, s_w) = if data.sx < 0 {
(0, (data.width - ((-data.sx) as u32)).min(var.xres))
} else {
let w = if data.sx as u32 + data.width > var.xres {
var.xres - data.sx as u32
} else {
data.width
};
(data.sx, w)
};
let (s_visiable_y, s_h) = if data.sy < 0 {
(0, (data.height - ((-data.sy) as u32).min(var.yres)))
} else {
let h = if data.sy as u32 + data.height > var.yres {
var.yres - data.sy as u32
} else {
data.height
};
(data.sy, h)
};
let (d_visiable_x, d_w) = if data.dx < 0 {
(0, (data.width - ((-data.dx) as u32)).min(var.xres))
} else {
let w = if data.dx as u32 + data.width > var.xres {
var.xres - data.dx as u32
} else {
data.width
};
(data.dx, w)
};
let (d_visiable_y, d_h) = if data.dy < 0 {
(0, (data.height - ((-data.dy) as u32).min(var.yres)))
} else {
let h = if data.dy as u32 + data.height > var.yres {
var.yres - data.dy as u32
} else {
data.height
};
(data.dy, h)
};
// 可视范围无交集
if !(d_h + s_h > data.height && s_w + d_w > data.width) {
return;
}
// 可视区域左上角相对于矩形的坐标
let s_relative_x = s_visiable_x - data.sx;
let s_relative_y = s_visiable_y - data.sy;
let d_relative_x = d_visiable_x - data.dx;
let d_relative_y = d_visiable_y - data.dy;
let visiable_x = s_relative_x.max(d_relative_x);
let visiable_y = s_relative_y.max(d_relative_y);
let visiable_h = d_h + s_h - data.height;
let visiable_w = d_w + s_w - data.width;
let s_real_x = (visiable_x + data.sx) as u32;
let s_real_y = (visiable_y + data.sy) as u32;
let d_real_x = (visiable_x + data.dx) as u32;
let d_real_y = (visiable_y + data.dy) as u32;
let bytes_per_pixel = var.bits_per_pixel >> 3; let bytes_per_pixel = var.bits_per_pixel >> 3;
let bytes_per_line = var.xres * bytes_per_pixel; let bytes_per_line = var.xres * bytes_per_pixel;
let sy = data.sy as u32; let src =
let sx = data.sx as u32; base + VirtAddr::new((s_real_y * bytes_per_line + s_real_x * bytes_per_pixel) as usize);
let dst = { let dst =
let mut dst = base; base + VirtAddr::new((d_real_y * bytes_per_line + d_real_x * bytes_per_pixel) as usize);
if data.dy < 0 {
dst -= VirtAddr::new((((-data.dy) as u32) * bytes_per_line) as usize);
} else {
dst += VirtAddr::new(((data.dy as u32) * bytes_per_line) as usize);
}
if data.dx > 0 && (data.dx as u32) < var.xres { let size = (visiable_h * visiable_w) as usize;
dst += VirtAddr::new(((data.dx as u32) * bytes_per_pixel) as usize);
}
dst
};
let src = base + VirtAddr::new((sy * bytes_per_line + sx * bytes_per_pixel) as usize);
match bytes_per_pixel { match bytes_per_pixel {
4 => { 4 => {
// 32bpp // 32bpp
let mut dst = dst.as_ptr::<u32>(); let mut dst = dst.as_ptr::<u32>();
let mut src = src.as_ptr::<u32>(); let mut src = src.as_ptr::<u32>();
let line_offset = var.xres as usize;
for y in 0..data.height as usize { if s_real_x > d_real_x {
if (data.dy + y as i32) < 0 || (data.dy + y as i32) > var.yres as i32 { // 如果src在dst下方则可以直接拷贝不会出现指针覆盖
unsafe { unsafe {
// core::ptr::copy(src, dst, data.width as usize); for _ in 0..visiable_h {
src = src.add(var.xres as usize); core::ptr::copy(src, dst, visiable_w as usize);
dst = dst.add(var.xres as usize); src = src.add(line_offset);
dst = dst.add(visiable_w as usize);
} }
continue;
} }
if data.dx < 0 { } else {
if ((-data.dx) as u32) < data.width { let mut tmp: Vec<u32> = Vec::with_capacity(size);
unsafe { tmp.resize(size, 0);
core::ptr::copy( let mut tmp_ptr = tmp.as_mut_ptr();
src.add((-data.dx) as usize),
dst, // 这里是一个可以优化的点现在为了避免指针拷贝时覆盖统一先拷贝进入buf再拷贝到dst
(data.width as usize) - (-data.dx) as usize, unsafe {
); for _ in 0..visiable_h {
src = src.add(var.xres as usize); core::ptr::copy(src, tmp_ptr, visiable_w as usize);
dst = dst.add(var.xres as usize); src = src.add(line_offset);
} tmp_ptr = tmp_ptr.add(visiable_w as usize);
} }
} else if data.dx as u32 + data.width > var.xres {
if (data.dx as u32) < var.xres { tmp_ptr = tmp_ptr.sub(size);
unsafe { for _ in 0..visiable_h {
core::ptr::copy(src, dst, (var.xres - data.dx as u32) as usize); core::ptr::copy(tmp_ptr, dst, visiable_w as usize);
src = src.add(var.xres as usize); dst = dst.add(line_offset);
dst = dst.add(var.xres as usize); tmp_ptr = tmp_ptr.add(visiable_w as usize);
}
}
} else {
for i in 0..data.width as usize {
unsafe { *(dst.add(i)) = *(src.add(i)) }
}
unsafe {
// core::ptr::copy(src, dst, data.width as usize);
src = src.add(var.xres as usize);
dst = dst.add(var.xres as usize);
} }
} }
} }
@ -506,7 +558,6 @@ impl FrameBufferOps for VesaFb {
todo!() todo!()
} }
} }
Ok(())
} }
} }

View File

@ -484,7 +484,18 @@ impl File {
let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap(); let inode = self.inode.downcast_ref::<LockedPipeInode>().unwrap();
return inode.inner().lock().add_epoll(epitem); return inode.inner().lock().add_epoll(epitem);
} }
_ => return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP), _ => {
let r = self.inode.ioctl(
EventPoll::ADD_EPOLLITEM,
&epitem as *const Arc<EPollItem> as usize,
&self.private_data,
);
if r.is_err() {
return Err(SystemError::ENOSYS);
}
Ok(())
}
} }
} }

View File

@ -369,6 +369,11 @@ impl IndexNode for MountFSInode {
fn special_node(&self) -> Option<super::SpecialNodeData> { fn special_node(&self) -> Option<super::SpecialNodeData> {
self.inner_inode.special_node() self.inner_inode.special_node()
} }
#[inline]
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
self.inner_inode.poll(private_data)
}
} }
impl FileSystem for MountFS { impl FileSystem for MountFS {

View File

@ -86,7 +86,7 @@ impl Signal {
return Err(SystemError::EINVAL); return Err(SystemError::EINVAL);
} }
// kdebug!("force send={}", force_send); // kdebug!("force send={}", force_send);
let pcb_info = pcb.sig_info(); let pcb_info = pcb.sig_info_irqsave();
let pending = if matches!(pt, PidType::PID) { let pending = if matches!(pt, PidType::PID) {
pcb_info.sig_shared_pending() pcb_info.sig_shared_pending()
} else { } else {
@ -189,7 +189,11 @@ impl Signal {
#[inline] #[inline]
fn wants_signal(&self, pcb: Arc<ProcessControlBlock>) -> bool { fn wants_signal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
// 如果改进程屏蔽了这个signal则不能接收 // 如果改进程屏蔽了这个signal则不能接收
if pcb.sig_info().sig_block().contains(self.clone().into()) { if pcb
.sig_info_irqsave()
.sig_block()
.contains(self.clone().into())
{
return false; return false;
} }
@ -209,7 +213,7 @@ impl Signal {
// todo: 检查目标进程是否正在一个cpu上执行如果是则返回true否则继续检查下一项 // todo: 检查目标进程是否正在一个cpu上执行如果是则返回true否则继续检查下一项
// 检查目标进程是否有信号正在等待处理如果是则返回false否则返回true // 检查目标进程是否有信号正在等待处理如果是则返回false否则返回true
if pcb.sig_info().sig_pending().signal().bits() == 0 { if pcb.sig_info_irqsave().sig_pending().signal().bits() == 0 {
return true; return true;
} else { } else {
return false; return false;
@ -263,7 +267,11 @@ impl Signal {
} }
// 一个被阻塞了的信号肯定是要被处理的 // 一个被阻塞了的信号肯定是要被处理的
if pcb.sig_info().sig_block().contains(self.into_sigset()) { if pcb
.sig_info_irqsave()
.sig_block()
.contains(self.into_sigset())
{
return true; return true;
} }
return !pcb.sig_struct().handlers[self.clone() as usize - 1].is_ignore(); return !pcb.sig_struct().handlers[self.clone() as usize - 1].is_ignore();
@ -430,7 +438,7 @@ pub fn set_current_sig_blocked(new_set: &mut SigSet) {
pcb的sig_blocked和新的相等 pcb的sig_blocked和新的相等
sig_blocked字段不能被其他进程修改 sig_blocked字段不能被其他进程修改
*/ */
if pcb.sig_info().sig_block().eq(new_set) { if pcb.sig_info_irqsave().sig_block().eq(new_set) {
return; return;
} }

View File

@ -599,7 +599,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
io_mfence(); io_mfence();
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
char buf[4096]; // vsprintf()的缓冲区 static char buf[4096]; // vsprintf()的缓冲区
int len = vsprintf(buf, fmt, args); int len = vsprintf(buf, fmt, args);
va_end(args); va_end(args);

View File

@ -218,6 +218,23 @@ impl<T> RwLock<T> {
return r; return r;
} //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak } //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
#[allow(dead_code)]
#[inline]
pub fn try_write_irqsave(&self) -> Option<RwLockWriteGuard<T>> {
ProcessManager::preempt_disable();
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let r = self.inner_try_write().map(|mut g| {
g.irq_guard = Some(irq_guard);
g
});
if r.is_none() {
ProcessManager::preempt_enable();
}
return r;
}
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
#[allow(dead_code)] #[allow(dead_code)]
fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> { fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> {

View File

@ -52,6 +52,8 @@ pub struct EventPoll {
impl EventPoll { impl EventPoll {
pub const EP_MAX_EVENTS: u32 = INT32_MAX / (core::mem::size_of::<EPollEvent>() as u32); pub const EP_MAX_EVENTS: u32 = INT32_MAX / (core::mem::size_of::<EPollEvent>() as u32);
/// 用于获取inode中的epitem队列
pub const ADD_EPOLLITEM: u32 = 0x7965;
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
epoll_wq: WaitQueue::INIT, epoll_wq: WaitQueue::INIT,
@ -462,7 +464,7 @@ impl EventPoll {
} }
// 如果有未处理的信号则返回错误 // 如果有未处理的信号则返回错误
if current_pcb.sig_info().sig_pending().signal().bits() != 0 { if current_pcb.sig_info_irqsave().sig_pending().signal().bits() != 0 {
return Err(SystemError::EINTR); return Err(SystemError::EINTR);
} }

View File

@ -363,12 +363,12 @@ impl ProcessManager {
// 设置clear_child_tid在线程结束时将其置0以通知父进程 // 设置clear_child_tid在线程结束时将其置0以通知父进程
if clone_flags.contains(CloneFlags::CLONE_CHILD_CLEARTID) { if clone_flags.contains(CloneFlags::CLONE_CHILD_CLEARTID) {
pcb.thread.write().clear_child_tid = Some(clone_args.child_tid); pcb.thread.write_irqsave().clear_child_tid = Some(clone_args.child_tid);
} }
// 设置child_tid意味着子线程能够知道自己的id // 设置child_tid意味着子线程能够知道自己的id
if clone_flags.contains(CloneFlags::CLONE_CHILD_SETTID) { if clone_flags.contains(CloneFlags::CLONE_CHILD_SETTID) {
pcb.thread.write().set_child_tid = Some(clone_args.child_tid); pcb.thread.write_irqsave().set_child_tid = Some(clone_args.child_tid);
} }
// 将子进程/线程的id存储在用户态传进的地址中 // 将子进程/线程的id存储在用户态传进的地址中
@ -424,13 +424,14 @@ impl ProcessManager {
// 设置线程组id、组长 // 设置线程组id、组长
if clone_flags.contains(CloneFlags::CLONE_THREAD) { if clone_flags.contains(CloneFlags::CLONE_THREAD) {
pcb.thread.write().group_leader = current_pcb.thread.read().group_leader.clone(); pcb.thread.write_irqsave().group_leader =
current_pcb.thread.read_irqsave().group_leader.clone();
unsafe { unsafe {
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock; let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
(*ptr).tgid = current_pcb.tgid; (*ptr).tgid = current_pcb.tgid;
} }
} else { } else {
pcb.thread.write().group_leader = Arc::downgrade(&pcb); pcb.thread.write_irqsave().group_leader = Arc::downgrade(&pcb);
unsafe { unsafe {
let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock; let ptr = pcb.as_ref() as *const ProcessControlBlock as *mut ProcessControlBlock;
(*ptr).tgid = pcb.tgid; (*ptr).tgid = pcb.tgid;
@ -439,12 +440,13 @@ impl ProcessManager {
// CLONE_PARENT re-uses the old parent // CLONE_PARENT re-uses the old parent
if clone_flags.contains(CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD) { if clone_flags.contains(CloneFlags::CLONE_PARENT | CloneFlags::CLONE_THREAD) {
*pcb.real_parent_pcb.write() = current_pcb.real_parent_pcb.read().clone(); *pcb.real_parent_pcb.write_irqsave() =
current_pcb.real_parent_pcb.read_irqsave().clone();
if clone_flags.contains(CloneFlags::CLONE_THREAD) { if clone_flags.contains(CloneFlags::CLONE_THREAD) {
pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst); pcb.exit_signal.store(Signal::INVALID, Ordering::SeqCst);
} else { } else {
let leader = current_pcb.thread.read().group_leader(); let leader = current_pcb.thread.read_irqsave().group_leader();
if unlikely(leader.is_none()) { if unlikely(leader.is_none()) {
panic!( panic!(
"fork: Failed to get leader of current process, current pid: [{:?}]", "fork: Failed to get leader of current process, current pid: [{:?}]",
@ -459,7 +461,7 @@ impl ProcessManager {
} }
} else { } else {
// 新创建的进程,设置其父进程为当前进程 // 新创建的进程,设置其父进程为当前进程
*pcb.real_parent_pcb.write() = Arc::downgrade(&current_pcb); *pcb.real_parent_pcb.write_irqsave() = Arc::downgrade(&current_pcb);
pcb.exit_signal pcb.exit_signal
.store(clone_args.exit_signal, Ordering::SeqCst); .store(clone_args.exit_signal, Ordering::SeqCst);
} }

View File

@ -311,7 +311,7 @@ impl ProcessManager {
.adopt_childen() .adopt_childen()
.unwrap_or_else(|e| panic!("adopte_childen failed: error: {e:?}")) .unwrap_or_else(|e| panic!("adopte_childen failed: error: {e:?}"))
}; };
let r = current.parent_pcb.read().upgrade(); let r = current.parent_pcb.read_irqsave().upgrade();
if r.is_none() { if r.is_none() {
return; return;
} }
@ -344,7 +344,7 @@ impl ProcessManager {
pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true))); pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true)));
// 进行进程退出后的工作 // 进行进程退出后的工作
let thread = pcb.thread.write(); let thread = pcb.thread.write_irqsave();
if let Some(addr) = thread.set_child_tid { if let Some(addr) = thread.set_child_tid {
unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") }; unsafe { clear_user(addr, core::mem::size_of::<i32>()).expect("clear tid failed") };
} }
@ -668,7 +668,7 @@ impl ProcessControlBlock {
// 将当前pcb加入父进程的子进程哈希表中 // 将当前pcb加入父进程的子进程哈希表中
if pcb.pid() > Pid(1) { if pcb.pid() > Pid(1) {
if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() { if let Some(ppcb_arc) = pcb.parent_pcb.read_irqsave().upgrade() {
let mut children = ppcb_arc.children.write_irqsave(); let mut children = ppcb_arc.children.write_irqsave();
children.push(pcb.pid()); children.push(pcb.pid());
} else { } else {
@ -718,7 +718,7 @@ impl ProcessControlBlock {
/// 否则会导致死锁 /// 否则会导致死锁
#[inline(always)] #[inline(always)]
pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> { pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> {
return self.basic.read(); return self.basic.read_irqsave();
} }
#[inline(always)] #[inline(always)]
@ -841,17 +841,13 @@ impl ProcessControlBlock {
return name; return name;
} }
pub fn sig_info(&self) -> RwLockReadGuard<ProcessSignalInfo> {
self.sig_info.read()
}
pub fn sig_info_irqsave(&self) -> RwLockReadGuard<ProcessSignalInfo> { pub fn sig_info_irqsave(&self) -> RwLockReadGuard<ProcessSignalInfo> {
self.sig_info.read_irqsave() self.sig_info.read_irqsave()
} }
pub fn try_siginfo(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> { pub fn try_siginfo_irqsave(&self, times: u8) -> Option<RwLockReadGuard<ProcessSignalInfo>> {
for _ in 0..times { for _ in 0..times {
if let Some(r) = self.sig_info.try_read() { if let Some(r) = self.sig_info.try_read_irqsave() {
return Some(r); return Some(r);
} }
} }
@ -865,7 +861,7 @@ impl ProcessControlBlock {
pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> { pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
for _ in 0..times { for _ in 0..times {
if let Some(r) = self.sig_info.try_write() { if let Some(r) = self.sig_info.try_write_irqsave() {
return Some(r); return Some(r);
} }
} }
@ -874,10 +870,10 @@ impl ProcessControlBlock {
} }
pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> { pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> {
self.sig_struct.lock() self.sig_struct.lock_irqsave()
} }
pub fn try_sig_struct_irq(&self, times: u8) -> Option<SpinLockGuard<SignalStruct>> { pub fn try_sig_struct_irqsave(&self, times: u8) -> Option<SpinLockGuard<SignalStruct>> {
for _ in 0..times { for _ in 0..times {
if let Ok(r) = self.sig_struct.try_lock_irqsave() { if let Ok(r) = self.sig_struct.try_lock_irqsave() {
return Some(r); return Some(r);
@ -894,13 +890,19 @@ impl ProcessControlBlock {
impl Drop for ProcessControlBlock { impl Drop for ProcessControlBlock {
fn drop(&mut self) { fn drop(&mut self) {
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
// kdebug!("drop: {:?}", self.pid);
// 在ProcFS中,解除进程的注册 // 在ProcFS中,解除进程的注册
procfs_unregister_pid(self.pid()) procfs_unregister_pid(self.pid())
.unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}")); .unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}"));
if let Some(ppcb) = self.parent_pcb.read().upgrade() { if let Some(ppcb) = self.parent_pcb.read_irqsave().upgrade() {
ppcb.children.write().retain(|pid| *pid != self.pid()); ppcb.children
.write_irqsave()
.retain(|pid| *pid != self.pid());
} }
drop(irq_guard);
} }
} }

View File

@ -202,11 +202,11 @@ impl Syscall {
}); });
if flags.contains(CloneFlags::CLONE_VFORK) { if flags.contains(CloneFlags::CLONE_VFORK) {
pcb.thread.write().vfork_done = Some(vfork.clone()); pcb.thread.write_irqsave().vfork_done = Some(vfork.clone());
} }
if pcb.thread.read().set_child_tid.is_some() { if pcb.thread.read_irqsave().set_child_tid.is_some() {
let addr = pcb.thread.read().set_child_tid.unwrap(); let addr = pcb.thread.read_irqsave().set_child_tid.unwrap();
let mut writer = let mut writer =
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?; UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?; writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
@ -234,7 +234,7 @@ impl Syscall {
.map_err(|_| SystemError::EFAULT)?; .map_err(|_| SystemError::EFAULT)?;
let pcb = ProcessManager::current_pcb(); let pcb = ProcessManager::current_pcb();
pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr)); pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr));
Ok(pcb.pid.0) Ok(pcb.pid.0)
} }