mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
finish epoll implementation
This commit is contained in:
parent
47e01cc79e
commit
14f0965bd2
@ -119,7 +119,7 @@ fn external() {
|
||||
|
||||
fn try_process_serial() -> bool {
|
||||
match super::io::getchar_option() {
|
||||
Some(ch) => {
|
||||
Some(ch) => {is
|
||||
trace!("Get char {} from serial", ch);
|
||||
crate::trap::serial(ch);
|
||||
true
|
||||
|
@ -2,6 +2,7 @@ use core::fmt;
|
||||
|
||||
use super::ioctl::*;
|
||||
use super::FileHandle;
|
||||
use crate::syscall::EpollInstance;
|
||||
use crate::net::Socket;
|
||||
use crate::syscall::{SysError, SysResult};
|
||||
use alloc::boxed::Box;
|
||||
@ -15,6 +16,7 @@ use alloc::vec::Vec;
|
||||
pub enum FileLike {
|
||||
File(FileHandle),
|
||||
Socket(Box<dyn Socket>),
|
||||
EpollInstance(EpollInstance),
|
||||
}
|
||||
|
||||
impl FileLike {
|
||||
@ -22,6 +24,9 @@ impl FileLike {
|
||||
let len = match self {
|
||||
FileLike::File(file) => file.read(buf)?,
|
||||
FileLike::Socket(socket) => socket.read(buf).0?,
|
||||
FileLike::EpollInstance(instance) => {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
};
|
||||
Ok(len)
|
||||
}
|
||||
@ -29,6 +34,9 @@ impl FileLike {
|
||||
let len = match self {
|
||||
FileLike::File(file) => file.write(buf)?,
|
||||
FileLike::Socket(socket) => socket.write(buf, None)?,
|
||||
FileLike::EpollInstance(instance) => {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
};
|
||||
Ok(len)
|
||||
}
|
||||
@ -43,6 +51,9 @@ impl FileLike {
|
||||
FileLike::Socket(socket) => {
|
||||
socket.ioctl(request, arg1, arg2, arg3)?;
|
||||
}
|
||||
FileLike::EpollInstance(instance) => {
|
||||
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
@ -55,6 +66,9 @@ impl FileLike {
|
||||
let (read, write, error) = socket.poll();
|
||||
PollStatus { read, write, error }
|
||||
}
|
||||
FileLike::EpollInstance(instance) => {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
};
|
||||
Ok(status)
|
||||
}
|
||||
@ -67,6 +81,9 @@ impl FileLike {
|
||||
FileLike::Socket(socket) => {
|
||||
condvars.push(&(*crate::drivers::SOCKET_ACTIVITY));
|
||||
},
|
||||
FileLike::EpollInstance(instance) => {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -76,9 +93,14 @@ impl FileLike {
|
||||
FileLike::Socket(socket) => {
|
||||
//TODO
|
||||
}
|
||||
FileLike::EpollInstance(instance) => {
|
||||
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl fmt::Debug for FileLike {
|
||||
@ -86,6 +108,7 @@ impl fmt::Debug for FileLike {
|
||||
match self {
|
||||
FileLike::File(file) => write!(f, "File({:?})", file),
|
||||
FileLike::Socket(socket) => write!(f, "Socket({:?})", socket),
|
||||
FileLike::EpollInstance(instance) => write!(f, "EpollInstance()"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use rcore_fs::vfs::*;
|
||||
use super::ioctl::*;
|
||||
use crate::sync::Condvar;
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use crate::process::Process;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Stdin {
|
||||
@ -43,6 +44,8 @@ impl Stdin {
|
||||
pub fn can_read(&self) -> bool {
|
||||
return self.buf.lock().len() > 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@ -51,6 +54,7 @@ pub struct Stdout;
|
||||
lazy_static! {
|
||||
pub static ref STDIN: Arc<Stdin> = Arc::new(Stdin::default());
|
||||
pub static ref STDOUT: Arc<Stdout> = Arc::new(Stdout::default());
|
||||
pub static ref STDIN_EPOLL_LIST: Arc<VecDeque<(Arc<Process>, usize)>> = Arc::new(VecDeque::default());
|
||||
}
|
||||
|
||||
impl INode for Stdin {
|
||||
|
@ -1,13 +1,17 @@
|
||||
use super::*;
|
||||
use crate::process::processor;
|
||||
use crate::process::{processor, current_thread};
|
||||
use crate::thread;
|
||||
use alloc::collections::VecDeque;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use crate::process::Process;
|
||||
use rcore_thread::std_thread::Thread;
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Condvar {
|
||||
wait_queue: SpinNoIrqLock<VecDeque<Arc<thread::Thread>>>,
|
||||
pub epoll_queue: SpinNoIrqLock< VecDeque<(Arc<SpinNoIrqLock<Process>>, usize, usize, usize)> >,
|
||||
}
|
||||
|
||||
impl Condvar {
|
||||
@ -91,12 +95,16 @@ impl Condvar {
|
||||
|
||||
pub fn notify_one(&self) {
|
||||
if let Some(t) = self.wait_queue.lock().front() {
|
||||
self.epoll_callback(t);
|
||||
t.unpark();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn notify_all(&self) {
|
||||
let queue = self.wait_queue.lock();
|
||||
for t in queue.iter() {
|
||||
self.epoll_callback(t);
|
||||
t.unpark();
|
||||
}
|
||||
}
|
||||
@ -115,4 +123,46 @@ impl Condvar {
|
||||
|
||||
count
|
||||
}
|
||||
|
||||
pub fn add_epoll_list(condvar: &Condvar, proc: Arc<SpinNoIrqLock<Process>>, tid :usize, epfd: usize, fd: usize){
|
||||
condvar.epoll_queue.lock().push_back((proc, tid, epfd, fd));
|
||||
}
|
||||
|
||||
pub fn remove_epoll_list(condvar: &Condvar, tid :usize, epfd: usize, fd: usize) -> bool{
|
||||
let mut epoll_list = condvar.epoll_queue.lock();
|
||||
for idx in 0..epoll_list.len(){
|
||||
if epoll_list[idx].1 == tid && epoll_list[idx].2 == epfd && epoll_list[idx].3 == fd{
|
||||
epoll_list.remove(idx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn epoll_callback(&self, thread: &Arc<Thread>) {
|
||||
let epoll_list = self.epoll_queue.lock();
|
||||
if epoll_list.len() <= 0 {
|
||||
return;
|
||||
}
|
||||
for idx in 0..epoll_list.len(){
|
||||
let proc = &epoll_list[idx].0;
|
||||
let tid = &epoll_list[idx].1;
|
||||
let epfd = &epoll_list[idx].2;
|
||||
let fd = &epoll_list[idx].3;
|
||||
|
||||
if thread.id() == *tid {
|
||||
let mut proc = proc.lock();
|
||||
match proc.get_epoll_instance(*epfd) {
|
||||
Ok(instacne) => {
|
||||
let mut readylist = instacne.readyList.lock();
|
||||
if !readylist.contains(fd) {
|
||||
readylist.push_back(*fd);
|
||||
}
|
||||
}
|
||||
Err(r) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,11 +9,17 @@ use crate::drivers::SOCKET_ACTIVITY;
|
||||
use crate::trap::TICK_ACTIVITY;
|
||||
use crate::fs::*;
|
||||
use crate::memory::MemorySet;
|
||||
use crate::sync::Condvar;
|
||||
use crate::sync::{Condvar, SpinNoIrqLock};
|
||||
use alloc::{collections::BTreeMap};
|
||||
|
||||
use bitvec::prelude::{BitSlice, BitVec, LittleEndian};
|
||||
|
||||
use super::*;
|
||||
use bitflags::_core::task::Poll;
|
||||
use alloc::collections::VecDeque;
|
||||
use rcore_fs::vfs::PollStatus;
|
||||
use crate::net::server;
|
||||
use crate::process::Process;
|
||||
|
||||
impl Syscall<'_> {
|
||||
pub fn sys_read(&mut self, fd: usize, base: *mut u8, len: usize) -> SysResult {
|
||||
@ -273,7 +279,11 @@ impl Syscall<'_> {
|
||||
) -> SysResult {
|
||||
info!("epoll_create: size: {:?}", size);
|
||||
|
||||
return Ok(0);
|
||||
if (size as i32) < 0 {
|
||||
return Err(SysError::EINVAL);
|
||||
|
||||
}
|
||||
return self.sys_epoll_create1(0);
|
||||
|
||||
}
|
||||
|
||||
@ -283,7 +293,13 @@ impl Syscall<'_> {
|
||||
) -> SysResult {
|
||||
info!("epoll_create1: flags: {:?}", flags);
|
||||
|
||||
return Ok(0);
|
||||
let mut proc = self.process();
|
||||
|
||||
let epollInstance = EpollInstance::new(flags);
|
||||
let fd = proc.add_file(FileLike::EpollInstance(epollInstance));
|
||||
|
||||
println!("kernel> epoll create ");
|
||||
Ok(fd)
|
||||
}
|
||||
|
||||
pub fn sys_epoll_ctl(
|
||||
@ -291,9 +307,32 @@ impl Syscall<'_> {
|
||||
epfd: usize,
|
||||
op: usize,
|
||||
fd: usize,
|
||||
event: *mut PollEvents,
|
||||
event: *mut EpollEvent,
|
||||
) -> SysResult {
|
||||
return Ok(0);
|
||||
|
||||
let mut proc = self.process();
|
||||
if !proc.pid.is_init() {
|
||||
// we trust pid 0 process
|
||||
info!("sys_epoll_ctl: epfd: {}, op: {:?}, fd: {:#x}", epfd, op, fd);
|
||||
}
|
||||
|
||||
let slice = unsafe { self.vm().check_read_array(event, 1)? };
|
||||
|
||||
if proc.files.get(&fd).is_none(){
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
|
||||
let epollInstance = match proc.get_epoll_instance(epfd) {
|
||||
Ok(ins) => ins,
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
|
||||
let ret = epollInstance.epoll_ctl(&self.vm(),op, fd, event)?;
|
||||
|
||||
println!("kernel> epoll ctl");
|
||||
return Ok(ret);
|
||||
|
||||
}
|
||||
|
||||
@ -304,8 +343,7 @@ impl Syscall<'_> {
|
||||
maxevents: usize,
|
||||
timeout: usize,
|
||||
) -> SysResult {
|
||||
return Ok(0);
|
||||
|
||||
self.sys_epoll_pwait(epfd, events, maxevents, timeout, 0)
|
||||
}
|
||||
|
||||
pub fn sys_epoll_pwait(
|
||||
@ -313,11 +351,176 @@ impl Syscall<'_> {
|
||||
epfd: usize,
|
||||
events: *mut EpollEvent,
|
||||
maxevents: usize,
|
||||
timeout: usize,
|
||||
sigset_t: *mut SigSet_t,
|
||||
timeout_msecs: usize,
|
||||
sigset_t: usize,
|
||||
) -> SysResult {
|
||||
return Ok(0);
|
||||
info!("epoll_pwait: epfd: {}, timeout: {:?}", epfd, timeout_msecs);
|
||||
|
||||
let mut proc = self.process();
|
||||
let writeslice = unsafe { self.vm().check_write_array(events, maxevents)? };
|
||||
let epollInstance = proc.get_unmut_epoll_instance(epfd)?;
|
||||
let keys: Vec<_> = epollInstance.events.keys().cloned().collect();
|
||||
|
||||
for (k, v) in epollInstance.events.iter(){
|
||||
// if !v.contains(EpollEvent::EPOLLET) {
|
||||
match &proc.files.get(k) {
|
||||
None => {
|
||||
return Err(SysError::EINVAL);
|
||||
},
|
||||
Some(file_like) => {
|
||||
let status = file_like.poll()?;
|
||||
if status.write || status.read || status.error {
|
||||
epollInstance.readyList.lock().push_back(*k);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
drop(proc);
|
||||
|
||||
|
||||
let mut callbacks = alloc::vec![];
|
||||
for fd in &keys {
|
||||
let mut proc = self.process();
|
||||
match proc.files.get(&fd){
|
||||
None => {
|
||||
return Err(SysError::EINVAL);
|
||||
},
|
||||
Some(file_like) => {
|
||||
match file_like{
|
||||
FileLike::File(file) => {
|
||||
Condvar::add_epoll_list( &crate::fs::STDIN.pushed, self.thread.proc.clone(),
|
||||
thread::current().id(), epfd, *fd);
|
||||
callbacks.push((0, thread::current().id(), epfd, *fd));
|
||||
},
|
||||
FileLike::Socket(socket) => {
|
||||
Condvar::add_epoll_list( &(*crate::drivers::SOCKET_ACTIVITY), self.thread.proc.clone(),
|
||||
thread::current().id(), epfd, *fd);
|
||||
callbacks.push((1, thread::current().id(), epfd, *fd));
|
||||
},
|
||||
FileLike::EpollInstance(instance) => {
|
||||
return Err(SysError::EINVAL);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
drop(proc);
|
||||
}
|
||||
|
||||
let mut condvars = Vec::new();
|
||||
condvars.push(&(*TICK_ACTIVITY));
|
||||
condvars.push(&STDIN.pushed);
|
||||
condvars.push(&(*SOCKET_ACTIVITY));
|
||||
|
||||
|
||||
let begin_time_ms = crate::trap::uptime_msec();
|
||||
let condition = move || {
|
||||
use PollEvents as PE;
|
||||
let mut proc = self.process();
|
||||
|
||||
let epollInstance = match proc.get_epoll_instance(epfd) {
|
||||
Ok(ins) => ins,
|
||||
Err(err) => {
|
||||
return Some(Err(err));
|
||||
}
|
||||
};
|
||||
let readylist = epollInstance.readyList.lock().clone();
|
||||
// println!("readylist : {:?}", readylist);
|
||||
let mut events_num = 0;
|
||||
|
||||
for infd in readylist.iter() {
|
||||
let mut status: PollStatus = Default::default();
|
||||
{
|
||||
if proc.files.get(&infd).is_some() {
|
||||
let file_like = proc.files.get(&infd).unwrap();
|
||||
let _status = match file_like.poll() {
|
||||
Ok(ret) => ret,
|
||||
Err(err) => return Some(Err(err)),
|
||||
};
|
||||
status.write = _status.write;
|
||||
status.read = _status.read;
|
||||
status.error = _status.error;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let epollInstance = match proc.get_epoll_instance(epfd) {
|
||||
Ok(ins) => ins,
|
||||
Err(err) => {
|
||||
return Some(Err(err));
|
||||
}
|
||||
};
|
||||
let epollevent = epollInstance.events.get_mut(&infd)?;
|
||||
|
||||
if status.error {
|
||||
unsafe {
|
||||
let _ = epollevent.copy_result_to(EpollEvent::EPOLLERR, &self.vm(), events, events_num);
|
||||
}
|
||||
events_num += 1;
|
||||
}
|
||||
if status.read && epollevent.contains(EpollEvent::EPOLLIN) {
|
||||
unsafe {
|
||||
let _ = epollevent.copy_result_to(EpollEvent::EPOLLIN, &self.vm(), events, events_num);
|
||||
}
|
||||
events_num += 1;
|
||||
}
|
||||
if status.write && epollevent.contains(EpollEvent::EPOLLOUT) {
|
||||
unsafe {
|
||||
let _ = epollevent.copy_result_to(EpollEvent::EPOLLOUT, &self.vm(), events, events_num);
|
||||
}
|
||||
events_num += 1;
|
||||
}
|
||||
}
|
||||
// } else {
|
||||
// unsafe {
|
||||
// epollevent.copy_result_to(EpollEvent::EPOLLERR, &self.vm(), events, events_num);
|
||||
// }
|
||||
// events_num += 1;
|
||||
// }
|
||||
}
|
||||
|
||||
{
|
||||
let epollInstance = match proc.get_epoll_instance(epfd) {
|
||||
Ok(ins) => ins,
|
||||
Err(err) => {
|
||||
return Some(Err(err));
|
||||
}
|
||||
};
|
||||
let mut lock = epollInstance.readyList.lock();
|
||||
lock.retain(|x| false);
|
||||
}
|
||||
|
||||
drop(proc);
|
||||
|
||||
// some event happens, so evoke the process
|
||||
if events_num > 0 {
|
||||
return Some(Ok(events_num));
|
||||
}
|
||||
|
||||
let current_time_ms = crate::trap::uptime_msec();
|
||||
// time runs out, so the evoke the process
|
||||
if timeout_msecs < (1 << 31) && current_time_ms - begin_time_ms > timeout_msecs {
|
||||
return Some(Ok(0));
|
||||
}
|
||||
return None;
|
||||
};
|
||||
|
||||
let num = Condvar::wait_events(condvars.as_slice(), condition).unwrap();
|
||||
|
||||
for cb in callbacks.iter(){
|
||||
if cb.0 == 0 {
|
||||
if !Condvar::remove_epoll_list( &crate::fs::STDIN.pushed, cb.1, cb.2, cb.3){
|
||||
println!("something goes wrong");
|
||||
}
|
||||
}
|
||||
if cb.0 == 1 {
|
||||
if !Condvar::remove_epoll_list( &(*crate::drivers::SOCKET_ACTIVITY), cb.1, cb.2, cb.3){
|
||||
println!("something goes wrong");
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(num)
|
||||
}
|
||||
|
||||
pub fn sys_readv(&mut self, fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult {
|
||||
@ -1610,22 +1813,167 @@ impl FdSet {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SigSet_t {
|
||||
__val: [u64; 1024 / 8 / 8],
|
||||
|
||||
//#[derive(Clone)]
|
||||
pub struct EpollInstance {
|
||||
pub events: BTreeMap<usize, EpollEvent>,
|
||||
pub readyList: SpinNoIrqLock<VecDeque<usize>>,
|
||||
}
|
||||
|
||||
union epoll_data_t {
|
||||
impl Clone for EpollInstance {
|
||||
fn clone(&self) -> Self {
|
||||
EpollInstance::new(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl EpollInstance {
|
||||
pub fn new(flags: usize) -> Self {
|
||||
return EpollInstance {
|
||||
events: BTreeMap::new(),
|
||||
readyList: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn epoll_ctl(&mut self, vm: &MemorySet, op: usize, fd: usize, event: *mut EpollEvent) -> SysResult {
|
||||
match (op as i32) {
|
||||
EPollCtlOp::EPOLLCTLADD => {
|
||||
if self.events.get(&fd).is_none() {
|
||||
let evs = unsafe { vm.check_read_array(event, 1)? };
|
||||
for ev in evs.iter() {
|
||||
self.events.insert(fd, ev.clone());
|
||||
}
|
||||
} else {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
|
||||
}
|
||||
EPollCtlOp::EPOLLCTLMOD => {
|
||||
if self.events.get(&fd).is_some() {
|
||||
let evs = unsafe { vm.check_read_array(event, 1)? };
|
||||
for ev in evs.iter() {
|
||||
self.events.remove(&fd);
|
||||
self.events.insert(fd, ev.clone());
|
||||
}
|
||||
} else {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
}
|
||||
EPollCtlOp::EPOLLCTLDEL => {
|
||||
if self.events.get(&fd).is_some() {
|
||||
let evs = unsafe { vm.check_read_array(event, 1)? };
|
||||
for ev in evs.iter() {
|
||||
self.events.remove(&fd);
|
||||
}
|
||||
} else {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
|
||||
}
|
||||
_ => {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#[derive(Clone)]
|
||||
//union EpollData {
|
||||
// ptr: u64,
|
||||
// fd: i32,
|
||||
// v32: u32,
|
||||
// v64: u64,
|
||||
//}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EpollData {
|
||||
ptr: u64,
|
||||
fd: i32,
|
||||
v32: u32,
|
||||
v64: u64,
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
#[derive(Clone)]
|
||||
pub struct EpollEvent {
|
||||
events: u32, /* Epoll events */
|
||||
data: epoll_data_t, /* User data variable */
|
||||
data: EpollData, /* User data variable */
|
||||
}
|
||||
|
||||
impl EpollEvent{
|
||||
unsafe fn copy_result_to(&mut self, events: u32, vm: &MemorySet,
|
||||
baseAddr: *mut EpollEvent, idx: usize) -> SysResult{
|
||||
let tmp = self.events;
|
||||
self.events = events;
|
||||
|
||||
let addr = baseAddr as usize + idx * size_of::<EpollEvent>();
|
||||
let written_len = size_of::<EpollEvent>();
|
||||
let target = vm.check_write_array(addr as *mut u8, written_len)?;
|
||||
let source = slice::from_raw_parts(self as *mut EpollEvent as *const u8, written_len);
|
||||
target.copy_from_slice(source);
|
||||
self.events = tmp;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn contains(&self, events: u32) -> bool {
|
||||
if (self.events & events) == 0 {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EPollCtlOp;
|
||||
impl EPollCtlOp{
|
||||
const EPOLLCTLADD: i32 = 1; /* Add a file descriptor to the interface. */
|
||||
const EPOLLCTLDEL: i32 = 2; /* Remove a file descriptor from the interface. */
|
||||
const EPOLLCTLMOD: i32 = 3; /* Change file descriptor epoll_event structure. */
|
||||
}
|
||||
|
||||
|
||||
impl EpollEvent {
|
||||
const EPOLLIN: u32 = 0x001;
|
||||
const EPOLLOUT: u32 = 0x004;
|
||||
const EPOLLERR: u32 = 0x008;
|
||||
const EPOLLHUP: u32 = 0x010;
|
||||
|
||||
const EPOLLPRI: u32 = 0x002;
|
||||
const EPOLLRDNORM: u32 = 0x040;
|
||||
const EPOLLRDBAND: u32 = 0x080;
|
||||
const EPOLLWRNORM: u32 = 0x100;
|
||||
const EPOLLWRBAND: u32 = 0x200;
|
||||
const EPOLLMSG: u32 = 0x400;
|
||||
const EPOLLRDHUP: u32 = 0x2000;
|
||||
const EPOLLEXCLUSIVE: u32 = 1 << 28;
|
||||
const EPOLLWAKEUP: u32 = 1 << 29;
|
||||
const EPOLLONESHOT: u32 = 1 << 30;
|
||||
const EPOLLET: u32 = 1 << 31;
|
||||
}
|
||||
|
||||
|
||||
impl Process {
|
||||
pub fn get_epoll_instance(&mut self, fd: usize) -> Result<&mut EpollInstance, SysError> {
|
||||
match self.get_file_like(fd)? {
|
||||
FileLike::EpollInstance(instance) => Ok(instance),
|
||||
_ => Err(SysError::EPERM),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_unmut_epoll_instance(&self, fd: usize) -> Result<&EpollInstance, SysError> {
|
||||
match self.files.get(&fd) {
|
||||
Some(file_like) => {
|
||||
match file_like {
|
||||
FileLike::EpollInstance(instance) => Ok(&instance),
|
||||
_ => Err(SysError::EPERM),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return Err(SysError::EPERM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Pathname is interpreted relative to the current working directory(CWD)
|
||||
const AT_FDCWD: usize = -100isize as usize;
|
||||
|
@ -15,6 +15,7 @@ use crate::process::*;
|
||||
use crate::sync::{Condvar, MutexGuard, SpinNoIrq};
|
||||
use crate::thread;
|
||||
use crate::util;
|
||||
use crate::syscall::{EpollEvent};
|
||||
|
||||
pub use self::custom::*;
|
||||
pub use self::fs::*;
|
||||
@ -166,9 +167,12 @@ impl Syscall<'_> {
|
||||
self.sys_ppoll(args[0] as *mut PollFd, args[1], args[2] as *const TimeSpec)
|
||||
} // ignore sigmask
|
||||
SYS_EPOLL_CREATE1 => self.sys_epoll_create1(args[0]),
|
||||
SYS_EPOLL_CTL => self.sys_epoll_ctl(args[0], args[1], args[2], args[3] as *mut EpollEvent),
|
||||
SYS_EPOLL_PWAIT => self.sys_epoll_pwait(args[0], args[1] as *mut EpollEvent,
|
||||
args[2], args[3], args[4] as *mut SigSet_t),
|
||||
args[2], args[3], args[4]),
|
||||
SYS_EVENTFD2=> self.unimplemented("eventfd2", Err(SysError::EACCES)),
|
||||
|
||||
SYS_SOCKETPAIR => self.unimplemented("socketpair", Err(SysError::EACCES)),
|
||||
// file system
|
||||
SYS_STATFS => self.unimplemented("statfs", Err(SysError::EACCES)),
|
||||
SYS_FSTATFS => self.unimplemented("fstatfs", Err(SysError::EACCES)),
|
||||
@ -348,6 +352,7 @@ impl Syscall<'_> {
|
||||
if let Some(ret) = ret {
|
||||
ret
|
||||
} else {
|
||||
println!("unknown syscall id: {}, args: {:x?}", id, args);
|
||||
error!("unknown syscall id: {}, args: {:x?}", id, args);
|
||||
crate::trap::error(self.tf);
|
||||
}
|
||||
@ -424,6 +429,9 @@ impl Syscall<'_> {
|
||||
3 => self.sys_semctl(args[1], args[2], args[3], args[4] as isize),
|
||||
_ => return None,
|
||||
},
|
||||
SYS_EPOLL_CREATE => self.sys_epoll_create(args[0]),
|
||||
SYS_EPOLL_WAIT =>self.sys_epoll_wait(args[0], args[1] as *mut EpollEvent, args[2], args[3]),
|
||||
|
||||
_ => return None,
|
||||
};
|
||||
Some(ret)
|
||||
@ -459,8 +467,8 @@ impl Syscall<'_> {
|
||||
SYS_CHOWN => self.unimplemented("chown", Ok(0)),
|
||||
SYS_ARCH_PRCTL => self.sys_arch_prctl(args[0] as i32, args[1]),
|
||||
SYS_TIME => self.sys_time(args[0] as *mut u64),
|
||||
SYS_EPOLL_CREATE => self.unimplemented("epoll_create", Err(SysError::ENOSYS)),
|
||||
// SYS_EPOLL_WAIT =>self.sys_epoll_wait(args[0], args[1] as *mut EpollEvent, args[2], args[3]),
|
||||
SYS_EPOLL_CREATE => self.sys_epoll_create(args[0]),
|
||||
SYS_EPOLL_WAIT =>self.sys_epoll_wait(args[0], args[1] as *mut EpollEvent, args[2], args[3]),
|
||||
_ => return None,
|
||||
};
|
||||
Some(ret)
|
||||
|
@ -29,6 +29,7 @@ pub fn timer() {
|
||||
}
|
||||
|
||||
pub fn error(tf: &TrapFrame) -> ! {
|
||||
println!("kernel error");
|
||||
error!("{:#x?}", tf);
|
||||
unsafe {
|
||||
let mut proc = current_thread().proc.lock();
|
||||
|
Loading…
Reference in New Issue
Block a user