refactor(epoll): epoll syscall refactor (#1180)

* feat(epoll): Move epoll functionality into filesystem module

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* refactor(epoll): refactor epoll syscall

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* feat(epoll): move do_epoll_wait into epoll_utils

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

* fmt

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>

---------

Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
This commit is contained in:
火花 2025-05-27 14:05:18 +08:00 committed by GitHub
parent e9d82983e1
commit a951a88bee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 665 additions and 457 deletions

View File

@ -10,6 +10,7 @@ use crate::{
}, },
filesystem::{ filesystem::{
devpts::DevPtsFs, devpts::DevPtsFs,
epoll::EPollEventType,
vfs::{ vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE, file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE,
VFS_MAX_FOLLOW_SYMLINK_TIMES, VFS_MAX_FOLLOW_SYMLINK_TIMES,
@ -17,7 +18,6 @@ use crate::{
}, },
libs::spinlock::SpinLockGuard, libs::spinlock::SpinLockGuard,
mm::VirtAddr, mm::VirtAddr,
net::event_poll::EPollEventType,
syscall::user_access::UserBufferWriter, syscall::user_access::UserBufferWriter,
}; };

View File

@ -12,13 +12,13 @@ use system_error::SystemError;
use crate::{ use crate::{
driver::{base::device::device_number::DeviceNumber, tty::pty::ptm_driver}, driver::{base::device::device_number::DeviceNumber, tty::pty::ptm_driver},
filesystem::epoll::{EPollEventType, EPollItem},
libs::{ libs::{
rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard}, rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
wait_queue::EventWaitQueue, wait_queue::EventWaitQueue,
}, },
mm::VirtAddr, mm::VirtAddr,
net::event_poll::{EPollEventType, EPollItem},
process::{process_group::Pgid, session::Sid, ProcessControlBlock}, process::{process_group::Pgid, session::Sid, ProcessControlBlock},
syscall::user_access::{UserBufferReader, UserBufferWriter}, syscall::user_access::{UserBufferReader, UserBufferWriter},
}; };

View File

@ -25,6 +25,7 @@ use crate::{
}, },
filesystem::{ filesystem::{
devfs::{devfs_register, DevFS, DeviceINode}, devfs::{devfs_register, DevFS, DeviceINode},
epoll::EPollItem,
kernfs::KernFSInode, kernfs::KernFSInode,
vfs::{ vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata, file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata,
@ -37,7 +38,6 @@ use crate::{
spinlock::SpinLockGuard, spinlock::SpinLockGuard,
}, },
mm::VirtAddr, mm::VirtAddr,
net::event_poll::EPollItem,
process::ProcessManager, process::ProcessManager,
syscall::user_access::{UserBufferReader, UserBufferWriter}, syscall::user_access::{UserBufferReader, UserBufferWriter},
}; };

View File

@ -15,13 +15,12 @@ use crate::{
tty_driver::{TtyDriverFlag, TtyOperation}, tty_driver::{TtyDriverFlag, TtyOperation},
tty_job_control::TtyJobCtrlManager, tty_job_control::TtyJobCtrlManager,
}, },
filesystem::vfs::file::FileMode, filesystem::{epoll::EPollEventType, vfs::file::FileMode},
libs::{ libs::{
rwlock::RwLockReadGuard, rwlock::RwLockReadGuard,
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
}, },
mm::VirtAddr, mm::VirtAddr,
net::event_poll::EPollEventType,
process::{ProcessFlags, ProcessManager}, process::{ProcessFlags, ProcessManager},
syscall::{user_access::UserBufferWriter, Syscall}, syscall::{user_access::UserBufferWriter, Syscall},
}; };

View File

@ -5,8 +5,8 @@ use kdepends::thingbuf::mpsc;
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::{
filesystem::epoll::{event_poll::EventPoll, EPollEventType},
libs::spinlock::{SpinLock, SpinLockGuard}, libs::spinlock::{SpinLock, SpinLockGuard},
net::event_poll::{EPollEventType, EventPoll},
}; };
use super::tty_core::TtyCore; use super::tty_core::TtyCore;

View File

@ -3,21 +3,13 @@ use core::{
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
}; };
use alloc::{
collections::LinkedList,
sync::{Arc, Weak},
vec::Vec,
};
use system_error::SystemError;
use crate::{ use crate::{
filesystem::vfs::{ filesystem::vfs::{
file::{File, FileMode}, file::{File, FileMode},
FilePrivateData, IndexNode, Metadata, FilePrivateData,
}, },
libs::{ libs::{
rbtree::RBTree, rbtree::RBTree,
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
wait_queue::WaitQueue, wait_queue::WaitQueue,
}, },
@ -29,10 +21,14 @@ use crate::{
}, },
}; };
pub mod syscall; use alloc::{
collections::LinkedList,
sync::{Arc, Weak},
vec::Vec,
};
use system_error::SystemError;
#[derive(Debug, Clone)] use super::{fs::EPollInode, EPollCtlOption, EPollEvent, EPollEventType, EPollItem};
pub struct LockedEventPoll(Arc<SpinLock<EventPoll>>);
/// 内核的Epoll对象结构体当用户创建一个Epoll时内核就会创建一个该类型对象 /// 内核的Epoll对象结构体当用户创建一个Epoll时内核就会创建一个该类型对象
/// 它对应一个epfd /// 它对应一个epfd
@ -49,138 +45,6 @@ pub struct EventPoll {
self_ref: Option<Weak<SpinLock<EventPoll>>>, self_ref: Option<Weak<SpinLock<EventPoll>>>,
} }
/// EpollItem表示的是Epoll所真正管理的对象
/// 每当用户向Epoll添加描述符时都会注册一个新的EpollItemEpollItem携带了一些被监听的描述符的必要信息
#[derive(Debug)]
pub struct EPollItem {
/// 对应的Epoll
epoll: Weak<SpinLock<EventPoll>>,
/// 用户注册的事件
event: RwLock<EPollEvent>,
/// 监听的描述符
fd: i32,
/// 对应的文件
file: Weak<File>,
}
impl EPollItem {
pub fn new(
epoll: Weak<SpinLock<EventPoll>>,
events: EPollEvent,
fd: i32,
file: Weak<File>,
) -> Self {
Self {
epoll,
event: RwLock::new(events),
fd,
file,
}
}
pub fn epoll(&self) -> Weak<SpinLock<EventPoll>> {
self.epoll.clone()
}
pub fn event(&self) -> &RwLock<EPollEvent> {
&self.event
}
pub fn file(&self) -> Weak<File> {
self.file.clone()
}
pub fn fd(&self) -> i32 {
self.fd
}
/// ## 通过epoll_item来执行绑定文件的poll方法并获取到感兴趣的事件
fn ep_item_poll(&self) -> EPollEventType {
let file = self.file.upgrade();
if file.is_none() {
return EPollEventType::empty();
}
if let Ok(events) = file.unwrap().poll() {
let events = events as u32 & self.event.read().events;
return EPollEventType::from_bits_truncate(events);
}
return EPollEventType::empty();
}
}
/// ### Epoll文件的私有信息
#[derive(Debug, Clone)]
pub struct EPollPrivateData {
epoll: LockedEventPoll,
}
/// ### 该结构体将Epoll加入文件系统
#[derive(Debug)]
pub struct EPollInode {
epoll: LockedEventPoll,
}
impl EPollInode {
pub fn new(epoll: LockedEventPoll) -> Arc<Self> {
Arc::new(Self { epoll })
}
}
impl IndexNode for EPollInode {
fn read_at(
&self,
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
fn write_at(
&self,
_offset: usize,
_len: usize,
_buf: &[u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
todo!()
}
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn list(&self) -> Result<Vec<alloc::string::String>, SystemError> {
Err(SystemError::ENOSYS)
}
fn metadata(&self) -> Result<Metadata, SystemError> {
Ok(Metadata::default())
}
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
// 释放资源
let mut epoll = self.epoll.0.lock_irqsave();
epoll.close()?;
Ok(())
}
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(())
}
}
impl EventPoll { impl EventPoll {
pub const EP_MAX_EVENTS: u32 = u32::MAX / (core::mem::size_of::<EPollEvent>() as u32); pub const EP_MAX_EVENTS: u32 = u32::MAX / (core::mem::size_of::<EPollEvent>() as u32);
/// 用于获取inode中的epitem队列 /// 用于获取inode中的epitem队列
@ -196,7 +60,7 @@ impl EventPoll {
} }
/// 关闭epoll时执行的逻辑 /// 关闭epoll时执行的逻辑
fn close(&mut self) -> Result<(), SystemError> { pub(super) fn close(&mut self) -> Result<(), SystemError> {
// 唤醒epoll上面等待的所有进程 // 唤醒epoll上面等待的所有进程
self.shutdown.store(true, Ordering::SeqCst); self.shutdown.store(true, Ordering::SeqCst);
self.ep_wake_all(); self.ep_wake_all();
@ -812,131 +676,11 @@ impl EventPoll {
} }
} }
/// 与C兼容的Epoll事件结构体 #[derive(Debug, Clone)]
#[derive(Copy, Clone, Default)] pub struct LockedEventPoll(pub(super) Arc<SpinLock<EventPoll>>);
#[repr(packed)]
#[repr(C)] /// ### Epoll文件的私有信息
pub struct EPollEvent { #[derive(Debug, Clone)]
/// 表示触发的事件 pub struct EPollPrivateData {
events: u32, pub(super) epoll: LockedEventPoll,
/// 内核态不使用该字段,该字段由用户态自由使用,在事件发生时内核将会原样返回
data: u64,
}
impl Debug for EPollEvent {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let events = self.events;
let u64 = self.data;
f.debug_struct("epoll_event")
.field("events", &events)
.field("data", &u64)
.finish()
}
}
impl EPollEvent {
pub fn set_events(&mut self, events: u32) {
self.events = events;
}
pub fn events(&self) -> u32 {
self.events
}
pub fn set_data(&mut self, data: u64) {
self.data = data;
}
pub fn data(&self) -> u64 {
self.data
}
}
/// ## epoll_ctl函数的参数
#[derive(Debug, PartialEq)]
pub enum EPollCtlOption {
/// 注册新的文件描述符到epfd
Add,
/// 将对应的文件描述符从epfd中删除
Del,
/// 修改已经注册的文件描述符的监听事件
Mod,
}
impl EPollCtlOption {
pub fn from_op_num(op: usize) -> Result<Self, SystemError> {
match op {
1 => Ok(Self::Add),
2 => Ok(Self::Del),
3 => Ok(Self::Mod),
_ => Err(SystemError::EINVAL),
}
}
}
bitflags! {
#[allow(dead_code)]
pub struct EPollEventType: u32 {
/// 对应的描述符有新的数据可读时会触发
const EPOLLIN = 0x00000001;
/// 对应的描述符有紧急数据可读时会触发
const EPOLLPRI = 0x00000002;
/// 对应的描述符可以写入数据时会触发
const EPOLLOUT = 0x00000004;
/// 对应的描述符发生错误时会触发
const EPOLLERR = 0x00000008;
/// 对应的描述符被挂断(连接关闭)时会触发
const EPOLLHUP = 0x00000010;
/// 对应的描述符不是一个有效的文件描述符时会触发
const EPOLLNVAL = 0x00000020;
/// 普通数据可读,类似于`EPOLLIN`
const EPOLLRDNORM = 0x00000040;
/// 优先级带外数据可读
const EPOLLRDBAND = 0x00000080;
/// 普通数据可写,类似于'EPOLLOUT'
const EPOLLWRNORM = 0x00000100;
/// 优先级带外数据可写
const EPOLLWRBAND = 0x00000200;
/// 通过消息队列收到消息时会触
const EPOLLMSG = 0x00000400;
/// 对应的描述符被挂断(连接关闭)的一端发送了 FIN 时会触发(读关闭)
const EPOLLRDHUP = 0x00002000;
/// 以下为额外选项
///
/// 特定选项,用于异步 I/O目前未实现
const EPOLL_URING_WAKE = 1u32 << 27;
/// 设置epoll为独占模式
const EPOLLEXCLUSIVE = 1u32 << 28;
/// 允许在系统挂起时唤醒 epoll通常用于通过 eventfd 或 timerfd 唤醒 epoll,(通常与电源管理相关,未实现)
const EPOLLWAKEUP = 1u32 << 29;
/// 表示只监听一次事件,之后需要重新添加
const EPOLLONESHOT = 1u32 << 30;
/// 启用边缘触发模式(即只有下次触发事件时才会通过epoll_wait返回)
/// 对应为水平触发(默认)水平触发模式下若这次未处理完数据那epoll还会将其加入自己的就绪队列
const EPOLLET = 1u32 << 31;
/// 以下为组合码
const EPOLLINOUT_BITS = Self::EPOLLIN.bits | Self::EPOLLOUT.bits;
const EPOLLEXCLUSIVE_OK_BITS =
Self::EPOLLINOUT_BITS.bits
| Self::EPOLLERR.bits
| Self::EPOLLHUP.bits
| Self::EPOLLWAKEUP.bits
| Self::EPOLLET.bits
| Self::EPOLLEXCLUSIVE.bits;
const EP_PRIVATE_BITS =
Self::EPOLLWAKEUP.bits
| Self::EPOLLONESHOT.bits
| Self::EPOLLET.bits
| Self::EPOLLEXCLUSIVE.bits;
/// 表示epoll已经被释放但是在目前的设计中未用到
const POLLFREE = 0x4000;
/// listen状态的socket可以接受连接
const EPOLL_LISTEN_CAN_ACCEPT = Self::EPOLLIN.bits | Self::EPOLLRDNORM.bits;
}
} }

View File

@ -0,0 +1,77 @@
use crate::{
filesystem::vfs::{file::FileMode, FilePrivateData, IndexNode, Metadata},
libs::spinlock::SpinLockGuard,
};
use alloc::sync::Arc;
use alloc::vec::Vec;
use system_error::SystemError;
use super::event_poll::LockedEventPoll;
/// ### 该结构体将Epoll加入文件系统
#[derive(Debug)]
pub struct EPollInode {
pub epoll: LockedEventPoll,
}
impl EPollInode {
pub fn new(epoll: LockedEventPoll) -> Arc<Self> {
Arc::new(Self { epoll })
}
}
impl IndexNode for EPollInode {
fn read_at(
&self,
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
fn write_at(
&self,
_offset: usize,
_len: usize,
_buf: &[u8],
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
todo!()
}
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn list(&self) -> Result<Vec<alloc::string::String>, SystemError> {
Err(SystemError::ENOSYS)
}
fn metadata(&self) -> Result<Metadata, SystemError> {
Ok(Metadata::default())
}
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
// 释放资源
let mut epoll = self.epoll.0.lock_irqsave();
epoll.close()?;
Ok(())
}
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(())
}
}

View File

@ -0,0 +1,197 @@
use super::vfs::file::File;
use crate::libs::{rwlock::RwLock, spinlock::SpinLock};
use alloc::sync::Weak;
use core::fmt::Debug;
use event_poll::EventPoll;
use system_error::SystemError;
pub mod event_poll;
pub mod fs;
/// 与C兼容的Epoll事件结构体
#[derive(Copy, Clone, Default)]
#[repr(packed)]
#[repr(C)]
pub struct EPollEvent {
/// 表示触发的事件
events: u32,
/// 内核态不使用该字段,该字段由用户态自由使用,在事件发生时内核将会原样返回
data: u64,
}
impl Debug for EPollEvent {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let events = self.events;
let u64 = self.data;
f.debug_struct("epoll_event")
.field("events", &events)
.field("data", &u64)
.finish()
}
}
impl EPollEvent {
pub fn set_events(&mut self, events: u32) {
self.events = events;
}
pub fn events(&self) -> u32 {
self.events
}
pub fn set_data(&mut self, data: u64) {
self.data = data;
}
pub fn data(&self) -> u64 {
self.data
}
}
/// EpollItem表示的是Epoll所真正管理的对象
/// 每当用户向Epoll添加描述符时都会注册一个新的EpollItemEpollItem携带了一些被监听的描述符的必要信息
#[derive(Debug)]
pub struct EPollItem {
/// 对应的Epoll
epoll: Weak<SpinLock<EventPoll>>,
/// 用户注册的事件
event: RwLock<EPollEvent>,
/// 监听的描述符
fd: i32,
/// 对应的文件
file: Weak<File>,
}
impl EPollItem {
pub fn new(
epoll: Weak<SpinLock<EventPoll>>,
events: EPollEvent,
fd: i32,
file: Weak<File>,
) -> Self {
Self {
epoll,
event: RwLock::new(events),
fd,
file,
}
}
pub fn epoll(&self) -> Weak<SpinLock<EventPoll>> {
self.epoll.clone()
}
pub fn event(&self) -> &RwLock<EPollEvent> {
&self.event
}
pub fn file(&self) -> Weak<File> {
self.file.clone()
}
pub fn fd(&self) -> i32 {
self.fd
}
/// ## 通过epoll_item来执行绑定文件的poll方法并获取到感兴趣的事件
fn ep_item_poll(&self) -> EPollEventType {
let file = self.file.upgrade();
if file.is_none() {
return EPollEventType::empty();
}
if let Ok(events) = file.unwrap().poll() {
let events = events as u32 & self.event.read().events;
return EPollEventType::from_bits_truncate(events);
}
return EPollEventType::empty();
}
}
/// ## epoll_ctl函数的参数
#[derive(Debug, PartialEq)]
pub enum EPollCtlOption {
/// 注册新的文件描述符到epfd
Add,
/// 将对应的文件描述符从epfd中删除
Del,
/// 修改已经注册的文件描述符的监听事件
Mod,
}
impl EPollCtlOption {
pub fn from_op_num(op: usize) -> Result<Self, SystemError> {
match op {
1 => Ok(Self::Add),
2 => Ok(Self::Del),
3 => Ok(Self::Mod),
_ => Err(SystemError::EINVAL),
}
}
}
bitflags! {
#[allow(dead_code)]
pub struct EPollEventType: u32 {
/// 对应的描述符有新的数据可读时会触发
const EPOLLIN = 0x00000001;
/// 对应的描述符有紧急数据可读时会触发
const EPOLLPRI = 0x00000002;
/// 对应的描述符可以写入数据时会触发
const EPOLLOUT = 0x00000004;
/// 对应的描述符发生错误时会触发
const EPOLLERR = 0x00000008;
/// 对应的描述符被挂断(连接关闭)时会触发
const EPOLLHUP = 0x00000010;
/// 对应的描述符不是一个有效的文件描述符时会触发
const EPOLLNVAL = 0x00000020;
/// 普通数据可读,类似于`EPOLLIN`
const EPOLLRDNORM = 0x00000040;
/// 优先级带外数据可读
const EPOLLRDBAND = 0x00000080;
/// 普通数据可写,类似于'EPOLLOUT'
const EPOLLWRNORM = 0x00000100;
/// 优先级带外数据可写
const EPOLLWRBAND = 0x00000200;
/// 通过消息队列收到消息时会触
const EPOLLMSG = 0x00000400;
/// 对应的描述符被挂断(连接关闭)的一端发送了 FIN 时会触发(读关闭)
const EPOLLRDHUP = 0x00002000;
/// 以下为额外选项
///
/// 特定选项,用于异步 I/O目前未实现
const EPOLL_URING_WAKE = 1u32 << 27;
/// 设置epoll为独占模式
const EPOLLEXCLUSIVE = 1u32 << 28;
/// 允许在系统挂起时唤醒 epoll通常用于通过 eventfd 或 timerfd 唤醒 epoll,(通常与电源管理相关,未实现)
const EPOLLWAKEUP = 1u32 << 29;
/// 表示只监听一次事件,之后需要重新添加
const EPOLLONESHOT = 1u32 << 30;
/// 启用边缘触发模式(即只有下次触发事件时才会通过epoll_wait返回)
/// 对应为水平触发(默认)水平触发模式下若这次未处理完数据那epoll还会将其加入自己的就绪队列
const EPOLLET = 1u32 << 31;
/// 以下为组合码
const EPOLLINOUT_BITS = Self::EPOLLIN.bits | Self::EPOLLOUT.bits;
const EPOLLEXCLUSIVE_OK_BITS =
Self::EPOLLINOUT_BITS.bits
| Self::EPOLLERR.bits
| Self::EPOLLHUP.bits
| Self::EPOLLWAKEUP.bits
| Self::EPOLLET.bits
| Self::EPOLLEXCLUSIVE.bits;
const EP_PRIVATE_BITS =
Self::EPOLLWAKEUP.bits
| Self::EPOLLONESHOT.bits
| Self::EPOLLET.bits
| Self::EPOLLEXCLUSIVE.bits;
/// 表示epoll已经被释放但是在目前的设计中未用到
const POLLFREE = 0x4000;
/// listen状态的socket可以接受连接
const EPOLL_LISTEN_CAN_ACCEPT = Self::EPOLLIN.bits | Self::EPOLLRDNORM.bits;
}
}

View File

@ -1,10 +1,12 @@
use super::vfs::PollableInode; use super::vfs::PollableInode;
use crate::filesystem::vfs::file::{File, FileMode}; use crate::filesystem::vfs::file::{File, FileMode};
use crate::filesystem::vfs::syscall::ModeType; use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata}; use crate::filesystem::{
epoll::{event_poll::EventPoll, EPollEventType, EPollItem},
vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata},
};
use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::libs::spinlock::{SpinLock, SpinLockGuard};
use crate::libs::wait_queue::WaitQueue; use crate::libs::wait_queue::WaitQueue;
use crate::net::event_poll::{EPollEventType, EPollItem, EventPoll};
use crate::process::{ProcessFlags, ProcessManager}; use crate::process::{ProcessFlags, ProcessManager};
use crate::sched::SchedMode; use crate::sched::SchedMode;
use crate::syscall::Syscall; use crate::syscall::Syscall;

View File

@ -1,5 +1,6 @@
pub mod devfs; pub mod devfs;
pub mod devpts; pub mod devpts;
pub mod epoll;
pub mod eventfd; pub mod eventfd;
pub mod fat; pub mod fat;
pub mod kernfs; pub mod kernfs;

View File

@ -2,11 +2,11 @@ use core::ffi::c_int;
use crate::{ use crate::{
arch::ipc::signal::SigSet, arch::ipc::signal::SigSet,
filesystem::epoll::{event_poll::EventPoll, EPollCtlOption, EPollEvent, EPollEventType},
ipc::signal::{ ipc::signal::{
restore_saved_sigmask_unless, set_user_sigmask, RestartBlock, RestartBlockData, RestartFn, restore_saved_sigmask_unless, set_user_sigmask, RestartBlock, RestartBlockData, RestartFn,
}, },
mm::VirtAddr, mm::VirtAddr,
net::event_poll::{EPollCtlOption, EPollEvent, EPollEventType, EventPoll},
process::ProcessManager, process::ProcessManager,
syscall::{ syscall::{
user_access::{UserBufferReader, UserBufferWriter}, user_access::{UserBufferReader, UserBufferWriter},

View File

@ -10,10 +10,12 @@ use crate::{
base::{block::SeekFrom, device::DevicePrivateData}, base::{block::SeekFrom, device::DevicePrivateData},
tty::tty_device::TtyFilePrivateData, tty::tty_device::TtyFilePrivateData,
}, },
filesystem::procfs::ProcfsFilePrivateData, filesystem::{
epoll::{event_poll::EPollPrivateData, EPollItem},
procfs::ProcfsFilePrivateData,
},
ipc::pipe::PipeFsPrivateData, ipc::pipe::PipeFsPrivateData,
libs::{rwlock::RwLock, spinlock::SpinLock}, libs::{rwlock::RwLock, spinlock::SpinLock},
net::event_poll::{EPollItem, EPollPrivateData},
process::{cred::Cred, ProcessManager}, process::{cred::Cred, ProcessManager},
}; };

View File

@ -18,13 +18,13 @@ use crate::{
driver::base::{ driver::base::{
block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber, block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber,
}, },
filesystem::epoll::EPollItem,
ipc::pipe::LockedPipeInode, ipc::pipe::LockedPipeInode,
libs::{ libs::{
casting::DowncastArc, casting::DowncastArc,
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
}, },
mm::{fault::PageFaultMessage, VmFaultReason}, mm::{fault::PageFaultMessage, VmFaultReason},
net::event_poll::EPollItem,
time::PosixTimeSpec, time::PosixTimeSpec,
}; };

View File

@ -0,0 +1,49 @@
use crate::filesystem::epoll::event_poll::EventPoll;
use crate::filesystem::epoll::EPollEvent;
use crate::mm::VirtAddr;
use crate::syscall::user_access::UserBufferWriter;
use crate::time::PosixTimeSpec;
use system_error::SystemError;
/// System call handler for epoll_wait.
///
/// # Arguments
/// * `epfd` - File descriptor of the epoll instance
/// * `events` - User space address to store the events
/// * `max_events` - Maximum number of events to return
/// * `timeout` - Timeout in milliseconds, 0 for no wait, negative for infinite wait
///
/// # Returns
/// Returns the number of events ready or an error if the operation fails.
pub(super) fn do_epoll_wait(
epfd: i32,
events: VirtAddr,
max_events: i32,
timeout: i32,
) -> Result<usize, SystemError> {
if max_events <= 0 || max_events as u32 > EventPoll::EP_MAX_EVENTS {
return Err(SystemError::EINVAL);
}
let mut timespec = None;
if timeout == 0 {
timespec = Some(PosixTimeSpec::new(0, 0));
}
if timeout > 0 {
let sec: i64 = timeout as i64 / 1000;
let nsec: i64 = 1000000 * (timeout as i64 % 1000);
timespec = Some(PosixTimeSpec::new(sec, nsec))
}
// 从用户传入的地址中拿到epoll_events
let mut epds_writer = UserBufferWriter::new(
events.as_ptr::<EPollEvent>(),
max_events as usize * core::mem::size_of::<EPollEvent>(),
true,
)?;
let epoll_events = epds_writer.buffer::<EPollEvent>(0)?;
return EventPoll::epoll_wait(epfd, epoll_events, max_events, timespec);
}

View File

@ -52,6 +52,15 @@ mod sys_stat;
mod sys_write; mod sys_write;
mod sys_writev; mod sys_writev;
mod epoll_utils;
#[cfg(target_arch = "x86_64")]
mod sys_epoll_create;
mod sys_epoll_create1;
mod sys_epoll_ctl;
mod sys_epoll_pwait;
#[cfg(target_arch = "x86_64")]
mod sys_epoll_wait;
pub const SEEK_SET: u32 = 0; pub const SEEK_SET: u32 = 0;
pub const SEEK_CUR: u32 = 1; pub const SEEK_CUR: u32 = 1;
pub const SEEK_END: u32 = 2; pub const SEEK_END: u32 = 2;

View File

@ -0,0 +1,41 @@
//! System call handler for epoll creation.
use crate::arch::syscall::nr::SYS_EPOLL_CREATE;
use crate::filesystem::epoll::event_poll::EventPoll;
use crate::filesystem::vfs::file::FileMode;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysEpollCreateHandle;
impl Syscall for SysEpollCreateHandle {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
let max_size = Self::max_size(args);
if max_size < 0 {
return Err(SystemError::EINVAL);
}
return EventPoll::create_epoll(FileMode::empty());
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"max_size",
format!("{:#x}", Self::max_size(args) as usize),
)]
}
}
impl SysEpollCreateHandle {
fn max_size(args: &[usize]) -> i32 {
args[0] as i32
}
}
syscall_table_macros::declare_syscall!(SYS_EPOLL_CREATE, SysEpollCreateHandle);

View File

@ -0,0 +1,36 @@
//! System call handler for epoll_create1.
use crate::arch::syscall::nr::SYS_EPOLL_CREATE1;
use crate::filesystem::epoll::event_poll::EventPoll;
use crate::filesystem::vfs::file::FileMode;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysEpollCreate1Handle;
impl Syscall for SysEpollCreate1Handle {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
return EventPoll::create_epoll(Self::flags(args));
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"flags",
format!("{:#x}", Self::flags(args)),
)]
}
}
impl SysEpollCreate1Handle {
fn flags(args: &[usize]) -> FileMode {
FileMode::from_bits_truncate(args[0] as u32)
}
}
syscall_table_macros::declare_syscall!(SYS_EPOLL_CREATE1, SysEpollCreate1Handle);

View File

@ -0,0 +1,74 @@
//! System call handler for epoll_ctl.
use crate::arch::syscall::nr::SYS_EPOLL_CTL;
use crate::filesystem::epoll::event_poll::EventPoll;
use crate::filesystem::epoll::EPollCtlOption;
use crate::filesystem::epoll::EPollEvent;
use crate::mm::VirtAddr;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use crate::syscall::user_access::UserBufferReader;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysEpollCtlHandle;
impl Syscall for SysEpollCtlHandle {
fn num_args(&self) -> usize {
4
}
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
let op = EPollCtlOption::from_op_num(Self::op(args))?;
let mut epds = EPollEvent::default();
let event = Self::event(args);
let epfd = Self::epfd(args);
let fd = Self::fd(args);
if op != EPollCtlOption::Del {
// 不为EpollCtlDel时不允许传入空指针
if event.is_null() {
return Err(SystemError::EFAULT);
}
// 还是一样的问题C标准的epoll_event大小为12字节而内核实现的epoll_event内存对齐后为16字节
// 这样分别拷贝其实和整体拷贝差别不大,内核使用内存对其版本甚至可能提升性能
let epds_reader = UserBufferReader::new(
event.as_ptr::<EPollEvent>(),
core::mem::size_of::<EPollEvent>(),
true,
)?;
// 拷贝到内核
epds_reader.copy_one_from_user(&mut epds, 0)?;
}
return EventPoll::epoll_ctl_with_epfd(epfd, op, fd, epds, false);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("epfd", format!("{:#x}", Self::epfd(args) as usize)),
FormattedSyscallParam::new("op", format!("{:#x}", Self::op(args))),
FormattedSyscallParam::new("fd", format!("{:#x}", Self::fd(args) as usize)),
FormattedSyscallParam::new("event", format!("{:#x}", Self::event(args).data())),
]
}
}
impl SysEpollCtlHandle {
fn epfd(args: &[usize]) -> i32 {
args[0] as i32
}
fn op(args: &[usize]) -> usize {
args[1]
}
fn fd(args: &[usize]) -> i32 {
args[2] as i32
}
fn event(args: &[usize]) -> VirtAddr {
VirtAddr::new(args[3])
}
}
syscall_table_macros::declare_syscall!(SYS_EPOLL_CTL, SysEpollCtlHandle);

View File

@ -0,0 +1,79 @@
//! System call handler for epoll_pwait.
use crate::arch::ipc::signal::SigSet;
use crate::arch::syscall::nr::SYS_EPOLL_PWAIT;
use crate::ipc::signal::restore_saved_sigmask;
use crate::ipc::signal::set_user_sigmask;
use crate::mm::VirtAddr;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use crate::syscall::user_access::UserBufferReader;
use alloc::vec::Vec;
use system_error::SystemError;
use super::epoll_utils::do_epoll_wait;
pub struct SysEpollPwaitHandle;
impl Syscall for SysEpollPwaitHandle {
fn num_args(&self) -> usize {
5
}
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
let epfd = Self::epfd(args);
let epoll_event = Self::epoll_event(args);
let max_events = Self::max_events(args);
let timespec = Self::timespec(args);
let sigmask_addr = Self::sigmask_addr(args);
if sigmask_addr.is_null() {
return do_epoll_wait(epfd, epoll_event, max_events, timespec);
}
let sigmask_reader =
UserBufferReader::new(sigmask_addr, core::mem::size_of::<SigSet>(), true)?;
let mut sigmask = *sigmask_reader.read_one_from_user::<SigSet>(0)?;
set_user_sigmask(&mut sigmask);
let wait_ret = do_epoll_wait(epfd, epoll_event, max_events, timespec);
if wait_ret.is_err() && *wait_ret.as_ref().unwrap_err() != SystemError::EINTR {
restore_saved_sigmask();
}
wait_ret
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("epfd", format!("{:#x}", Self::epfd(args) as usize)),
FormattedSyscallParam::new("event", format!("{:#x}", Self::epoll_event(args).data())),
FormattedSyscallParam::new("max_events", format!("{:#x}", Self::max_events(args))),
FormattedSyscallParam::new("timespec", format!("{:#x}", Self::timespec(args))),
FormattedSyscallParam::new(
"sigmask_addr",
format!("{:#x}", Self::sigmask_addr(args) as usize),
),
]
}
}
impl SysEpollPwaitHandle {
fn epfd(args: &[usize]) -> i32 {
args[0] as i32
}
fn epoll_event(args: &[usize]) -> VirtAddr {
VirtAddr::new(args[1])
}
fn max_events(args: &[usize]) -> i32 {
args[2] as i32
}
fn timespec(args: &[usize]) -> i32 {
args[3] as i32
}
fn sigmask_addr(args: &[usize]) -> *mut SigSet {
args[4] as *mut SigSet
}
}
syscall_table_macros::declare_syscall!(SYS_EPOLL_PWAIT, SysEpollPwaitHandle);

View File

@ -0,0 +1,52 @@
//! System call handler for epoll_wait.
use super::epoll_utils::do_epoll_wait;
use crate::arch::syscall::nr::SYS_EPOLL_WAIT;
use crate::mm::VirtAddr;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysEpollWaitHandle;
impl Syscall for SysEpollWaitHandle {
fn num_args(&self) -> usize {
4
}
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
let epfd = Self::epfd(args);
let max_events = Self::max_events(args);
let timeout = Self::timeout(args);
let events = Self::events(args);
do_epoll_wait(epfd, events, max_events, timeout)
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("epfd", format!("{:#x}", Self::epfd(args) as usize)),
FormattedSyscallParam::new("events", format!("{:#x}", Self::events(args).data())),
FormattedSyscallParam::new("max_events", format!("{:#x}", Self::max_events(args))),
FormattedSyscallParam::new("timeout", format!("{:#x}", Self::timeout(args))),
]
}
}
impl SysEpollWaitHandle {
fn epfd(args: &[usize]) -> i32 {
args[0] as i32
}
fn events(args: &[usize]) -> VirtAddr {
VirtAddr::new(args[1])
}
fn max_events(args: &[usize]) -> i32 {
args[2] as i32
}
fn timeout(args: &[usize]) -> i32 {
args[3] as i32
}
}
syscall_table_macros::declare_syscall!(SYS_EPOLL_WAIT, SysEpollWaitHandle);

View File

@ -2,15 +2,17 @@ use core::sync::atomic::compiler_fence;
use crate::{ use crate::{
arch::ipc::signal::{SigCode, Signal}, arch::ipc::signal::{SigCode, Signal},
filesystem::vfs::{ filesystem::{
file::FileMode, syscall::ModeType, vcore::generate_inode_id, FilePrivateData, FileSystem, epoll::{event_poll::EventPoll, EPollEventType, EPollItem},
FileType, IndexNode, Metadata, PollableInode, vfs::{
file::FileMode, syscall::ModeType, vcore::generate_inode_id, FilePrivateData,
FileSystem, FileType, IndexNode, Metadata, PollableInode,
},
}, },
libs::{ libs::{
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
wait_queue::WaitQueue, wait_queue::WaitQueue,
}, },
net::event_poll::{EPollEventType, EPollItem, EventPoll},
process::{ProcessFlags, ProcessManager, ProcessState}, process::{ProcessFlags, ProcessManager, ProcessState},
sched::SchedMode, sched::SchedMode,
time::PosixTimeSpec, time::PosixTimeSpec,

View File

@ -1,108 +0,0 @@
use system_error::SystemError;
use crate::{
arch::ipc::signal::SigSet,
filesystem::vfs::file::FileMode,
ipc::signal::{restore_saved_sigmask, set_user_sigmask},
mm::VirtAddr,
syscall::{
user_access::{UserBufferReader, UserBufferWriter},
Syscall,
},
time::PosixTimeSpec,
};
use super::{EPollCtlOption, EPollEvent, EventPoll};
impl Syscall {
pub fn epoll_create(max_size: i32) -> Result<usize, SystemError> {
if max_size < 0 {
return Err(SystemError::EINVAL);
}
return EventPoll::create_epoll(FileMode::empty());
}
pub fn epoll_create1(flag: usize) -> Result<usize, SystemError> {
let flags = FileMode::from_bits_truncate(flag as u32);
let ret = EventPoll::create_epoll(flags);
ret
}
pub fn epoll_wait(
epfd: i32,
events: VirtAddr,
max_events: i32,
timeout: i32,
) -> Result<usize, SystemError> {
if max_events <= 0 || max_events as u32 > EventPoll::EP_MAX_EVENTS {
return Err(SystemError::EINVAL);
}
let mut timespec = None;
if timeout == 0 {
timespec = Some(PosixTimeSpec::new(0, 0));
}
if timeout > 0 {
let sec: i64 = timeout as i64 / 1000;
let nsec: i64 = 1000000 * (timeout as i64 % 1000);
timespec = Some(PosixTimeSpec::new(sec, nsec))
}
// 从用户传入的地址中拿到epoll_events
let mut epds_writer = UserBufferWriter::new(
events.as_ptr::<EPollEvent>(),
max_events as usize * core::mem::size_of::<EPollEvent>(),
true,
)?;
let epoll_events = epds_writer.buffer::<EPollEvent>(0)?;
return EventPoll::epoll_wait(epfd, epoll_events, max_events, timespec);
}
pub fn epoll_ctl(epfd: i32, op: usize, fd: i32, event: VirtAddr) -> Result<usize, SystemError> {
let op = EPollCtlOption::from_op_num(op)?;
let mut epds = EPollEvent::default();
if op != EPollCtlOption::Del {
// 不为EpollCtlDel时不允许传入空指针
if event.is_null() {
return Err(SystemError::EFAULT);
}
// 还是一样的问题C标准的epoll_event大小为12字节而内核实现的epoll_event内存对齐后为16字节
// 这样分别拷贝其实和整体拷贝差别不大,内核使用内存对其版本甚至可能提升性能
let epds_reader = UserBufferReader::new(
event.as_ptr::<EPollEvent>(),
core::mem::size_of::<EPollEvent>(),
true,
)?;
// 拷贝到内核
epds_reader.copy_one_from_user(&mut epds, 0)?;
}
return EventPoll::epoll_ctl_with_epfd(epfd, op, fd, epds, false);
}
/// ## 在epoll_wait时屏蔽某些信号
pub fn epoll_pwait(
epfd: i32,
epoll_event: VirtAddr,
max_events: i32,
timespec: i32,
sigmask: &mut SigSet,
) -> Result<usize, SystemError> {
// 设置屏蔽的信号
set_user_sigmask(sigmask);
let wait_ret = Self::epoll_wait(epfd, epoll_event, max_events, timespec);
if wait_ret.is_err() && *wait_ret.as_ref().unwrap_err() != SystemError::EINTR {
restore_saved_sigmask();
}
wait_ret
}
}

View File

@ -10,7 +10,6 @@ use smoltcp::wire::IpEndpoint;
use self::socket::SocketInode; use self::socket::SocketInode;
pub mod event_poll;
pub mod net_core; pub mod net_core;
pub mod socket; pub mod socket;
pub mod syscall; pub mod syscall;

View File

@ -3,8 +3,10 @@ use log::{debug, info, warn};
use smoltcp::{socket::dhcpv4, wire}; use smoltcp::{socket::dhcpv4, wire};
use system_error::SystemError; use system_error::SystemError;
use super::socket::{handle::GlobalSocketHandle, inet::TcpSocket, HANDLE_MAP, SOCKET_SET};
use crate::{ use crate::{
driver::net::{NetDevice, Operstate}, driver::net::{NetDevice, Operstate},
filesystem::epoll::{event_poll::EventPoll, EPollEventType},
libs::rwlock::RwLockReadGuard, libs::rwlock::RwLockReadGuard,
net::{socket::SocketPollMethod, NET_DEVICES}, net::{socket::SocketPollMethod, NET_DEVICES},
time::{ time::{
@ -14,11 +16,6 @@ use crate::{
}, },
}; };
use super::{
event_poll::{EPollEventType, EventPoll},
socket::{handle::GlobalSocketHandle, inet::TcpSocket, HANDLE_MAP, SOCKET_SET},
};
/// The network poll function, which will be called by timer. /// The network poll function, which will be called by timer.
/// ///
/// The main purpose of this function is to poll all network interfaces. /// The main purpose of this function is to poll all network interfaces.

View File

@ -8,11 +8,9 @@ use system_error::SystemError;
use crate::{ use crate::{
driver::net::NetDevice, driver::net::NetDevice,
filesystem::epoll::EPollEventType,
libs::rwlock::RwLock, libs::rwlock::RwLock,
net::{ net::{net_core::poll_ifaces, Endpoint, Protocol, ShutdownType, NET_DEVICES},
event_poll::EPollEventType, net_core::poll_ifaces, Endpoint, Protocol, ShutdownType,
NET_DEVICES,
},
}; };
use super::{ use super::{

View File

@ -17,9 +17,12 @@ use system_error::SystemError;
use crate::{ use crate::{
arch::rand::rand, arch::rand::rand,
filesystem::vfs::{ filesystem::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, epoll::{EPollEventType, EPollItem},
Metadata, PollableInode, vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode,
Metadata, PollableInode,
},
}, },
libs::{ libs::{
rwlock::{RwLock, RwLockWriteGuard}, rwlock::{RwLock, RwLockWriteGuard},
@ -36,10 +39,7 @@ use self::{
unix::{SeqpacketSocket, StreamSocket}, unix::{SeqpacketSocket, StreamSocket},
}; };
use super::{ use super::{Endpoint, Protocol, ShutdownType};
event_poll::{EPollEventType, EPollItem},
Endpoint, Protocol, ShutdownType,
};
pub mod handle; pub mod handle;
pub mod inet; pub mod inet;

View File

@ -2,6 +2,7 @@ mod bpf;
mod kprobe; mod kprobe;
mod util; mod util;
use crate::filesystem::epoll::{event_poll::EventPoll, EPollEventType, EPollItem};
use crate::filesystem::page_cache::PageCache; use crate::filesystem::page_cache::PageCache;
use crate::filesystem::vfs::file::{File, FileMode}; use crate::filesystem::vfs::file::{File, FileMode};
use crate::filesystem::vfs::syscall::ModeType; use crate::filesystem::vfs::syscall::ModeType;
@ -15,7 +16,6 @@ use crate::libs::casting::DowncastArc;
use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::libs::spinlock::{SpinLock, SpinLockGuard};
use crate::mm::fault::{PageFaultHandler, PageFaultMessage}; use crate::mm::fault::{PageFaultHandler, PageFaultMessage};
use crate::mm::VmFaultReason; use crate::mm::VmFaultReason;
use crate::net::event_poll::{EPollEventType, EPollItem, EventPoll};
use crate::perf::bpf::BpfPerfEvent; use crate::perf::bpf::BpfPerfEvent;
use crate::perf::util::{PerfEventIoc, PerfEventOpenFlags, PerfProbeArgs}; use crate::perf::util::{PerfEventIoc, PerfEventOpenFlags, PerfProbeArgs};
use crate::process::ProcessManager; use crate::process::ProcessManager;

View File

@ -4,7 +4,7 @@ use core::{
}; };
use crate::{ use crate::{
arch::{ipc::signal::SigSet, syscall::nr::*}, arch::syscall::nr::*,
filesystem::vfs::syscall::PosixStatfs, filesystem::vfs::syscall::PosixStatfs,
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey}, ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
libs::{futex::constant::FutexFlag, rand::GRandFlags}, libs::{futex::constant::FutexFlag, rand::GRandFlags},
@ -762,48 +762,6 @@ impl Syscall {
args[4], args[4],
), ),
#[cfg(target_arch = "x86_64")]
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
SYS_EPOLL_CREATE1 => Self::epoll_create1(args[0]),
SYS_EPOLL_CTL => Self::epoll_ctl(
args[0] as i32,
args[1],
args[2] as i32,
VirtAddr::new(args[3]),
),
#[cfg(target_arch = "x86_64")]
SYS_EPOLL_WAIT => Self::epoll_wait(
args[0] as i32,
VirtAddr::new(args[1]),
args[2] as i32,
args[3] as i32,
),
SYS_EPOLL_PWAIT => {
let epfd = args[0] as i32;
let epoll_event = VirtAddr::new(args[1]);
let max_events = args[2] as i32;
let timespec = args[3] as i32;
let sigmask_addr = args[4] as *mut SigSet;
if sigmask_addr.is_null() {
return Self::epoll_wait(epfd, epoll_event, max_events, timespec);
}
let sigmask_reader =
UserBufferReader::new(sigmask_addr, core::mem::size_of::<SigSet>(), true)?;
let mut sigmask = *sigmask_reader.read_one_from_user::<SigSet>(0)?;
Self::epoll_pwait(
args[0] as i32,
VirtAddr::new(args[1]),
args[2] as i32,
args[3] as i32,
&mut sigmask,
)
}
// 目前为了适配musl-libc,以下系统调用先这样写着 // 目前为了适配musl-libc,以下系统调用先这样写着
SYS_GETRANDOM => { SYS_GETRANDOM => {
let flags = GRandFlags::from_bits(args[2] as u8).ok_or(SystemError::EINVAL)?; let flags = GRandFlags::from_bits(args[2] as u8).ok_or(SystemError::EINVAL)?;