1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

change code structure

This commit is contained in:
ssryps 2019-11-07 22:57:13 +08:00
parent f6e5769a51
commit 0a1e422cac
6 changed files with 194 additions and 244 deletions

139
kernel/src/fs/epoll.rs Normal file
View File

@ -0,0 +1,139 @@
use alloc::{collections::BTreeMap, collections::BTreeSet};
use crate::syscall::{SysError, SysResult};
use core::slice;
use crate::sync::{Condvar, SpinNoIrqLock};
use crate::memory::MemorySet;
use core::mem::size_of;
use crate::process::Process;
use crate::fs::FileLike;
pub struct EpollInstance {
pub events: BTreeMap<usize, EpollEvent>,
pub readyList: SpinNoIrqLock<BTreeSet<usize>>,
pub newCtlList: SpinNoIrqLock<BTreeSet<usize>>,
}
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(),
newCtlList: Default::default(),
}
}
pub fn control(&mut self, op: usize, fd: usize, event: &EpollEvent) -> SysResult {
match (op as i32) {
EPollCtlOp::ADD => {
self.events.insert(fd, event.clone());
self.newCtlList.lock().insert(fd);
}
EPollCtlOp::MOD => {
if self.events.get(&fd).is_some() {
self.events.remove(&fd);
self.events.insert(fd, event.clone());
self.newCtlList.lock().insert(fd);
} else {
return Err(SysError::EPERM);
}
}
EPollCtlOp::DEL => {
if self.events.get(&fd).is_some() {
self.events.remove(&fd);
} else {
return Err(SysError::EPERM);
}
}
_ => {
return Err(SysError::EPERM);
}
}
Ok(0)
}
}
#[derive(Clone, Copy)]
pub struct EpollData {
ptr: u64,
}
#[repr(packed)]
#[derive(Clone)]
pub struct EpollEvent {
pub events: u32, /* Epoll events */
pub data: EpollData, /* User data variable */
}
impl EpollEvent{
pub const EPOLLIN: u32 = 0x001;
pub const EPOLLOUT: u32 = 0x004;
pub const EPOLLERR: u32 = 0x008;
pub const EPOLLHUP: u32 = 0x010;
pub const EPOLLPRI: u32 = 0x002;
pub const EPOLLRDNORM: u32 = 0x040;
pub const EPOLLRDBAND: u32 = 0x080;
pub const EPOLLWRNORM: u32 = 0x100;
pub const EPOLLWRBAND: u32 = 0x200;
pub const EPOLLMSG: u32 = 0x400;
pub const EPOLLRDHUP: u32 = 0x2000;
pub const EPOLLEXCLUSIVE: u32 = 1 << 28;
pub const EPOLLWAKEUP: u32 = 1 << 29;
pub const EPOLLONESHOT: u32 = 1 << 30;
pub const EPOLLET: u32 = 1 << 31;
pub fn contains(&self, events: u32) -> bool {
if (self.events & events) == 0 {
return false;
} else {
return true;
}
}
}
pub struct EPollCtlOp;
impl EPollCtlOp{
const ADD: i32 = 1; /* Add a file descriptor to the interface. */
const DEL: i32 = 2; /* Remove a file descriptor from the interface. */
const MOD: i32 = 3; /* Change file descriptor epoll_event structure. */
}
impl Process {
pub fn get_epoll_instance_mut(&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_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);
}
}
}
}

View File

@ -2,7 +2,7 @@ use core::fmt;
use super::ioctl::*;
use super::FileHandle;
use crate::syscall::EpollInstance;
use crate::fs::epoll::EpollInstance;
use crate::net::Socket;
use crate::syscall::{SysError, SysResult};
use alloc::boxed::Box;

View File

@ -18,6 +18,7 @@ pub use self::stdio::{STDIN, STDOUT};
pub use self::vga::*;
mod device;
pub mod epoll;
mod file;
mod file_like;
mod ioctl;

View File

@ -7,11 +7,17 @@ use alloc::vec::Vec;
use crate::process::Process;
use rcore_thread::std_thread::Thread;
pub struct RegisteredProcess {
proc: Arc<SpinNoIrqLock<Process>>,
tid: usize,
epfd: usize,
fd: usize,
}
#[derive(Default)]
pub struct Condvar {
wait_queue: SpinNoIrqLock<VecDeque<Arc<thread::Thread>>>,
pub epoll_queue: SpinNoIrqLock< VecDeque<(Arc<SpinNoIrqLock<Process>>, usize, usize, usize)> >,
pub epoll_queue: SpinNoIrqLock<VecDeque<RegisteredProcess>>,
}
impl Condvar {
@ -125,13 +131,19 @@ impl Condvar {
}
pub fn register_epoll_list(&self, proc: Arc<SpinNoIrqLock<Process>>, tid :usize, epfd: usize, fd: usize){
self.epoll_queue.lock().push_back((proc, tid, epfd, fd));
self.epoll_queue.lock().push_back(RegisteredProcess{
proc: proc,
tid: tid,
epfd: epfd,
fd: fd,
}
);
}
pub fn unregister_epoll_list(&self, tid :usize, epfd: usize, fd: usize) -> bool{
let mut epoll_list = self.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{
if epoll_list[idx].tid == tid && epoll_list[idx].epfd == epfd && epoll_list[idx].fd == fd{
epoll_list.remove(idx);
return true;
}
@ -141,15 +153,13 @@ impl Condvar {
fn epoll_callback(&self, thread: &Arc<Thread>) {
let epoll_list = self.epoll_queue.lock();
for (proc, tid, epfd, fd) in epoll_list.iter() {
if thread.id() == *tid {
let mut proc = proc.lock();
match proc.get_epoll_instance(*epfd) {
for ist in epoll_list.iter() {
if thread.id() == ist.tid {
let mut proc = ist.proc.lock();
match proc.get_epoll_instance(ist.epfd) {
Ok(instacne) => {
let mut readylist = instacne.readyList.lock();
if !readylist.contains(fd) {
readylist.push_back(*fd);
}
readylist.insert(ist.fd);
}
Err(r) => {
panic!("epoll instance not exist");

View File

@ -10,7 +10,7 @@ use crate::trap::TICK_ACTIVITY;
use crate::fs::*;
use crate::memory::MemorySet;
use crate::sync::{Condvar, SpinNoIrqLock};
use alloc::{collections::BTreeMap};
use alloc::{collections::BTreeMap, collections::BTreeSet};
use bitvec::prelude::{BitSlice, BitVec, LittleEndian};
@ -20,6 +20,7 @@ use alloc::collections::VecDeque;
use rcore_fs::vfs::PollStatus;
use crate::net::server;
use crate::process::Process;
use crate::fs::epoll::EpollInstance;
impl Syscall<'_> {
pub fn sys_read(&mut self, fd: usize, base: *mut u8, len: usize) -> SysResult {
@ -108,16 +109,7 @@ impl Syscall<'_> {
let mut condvars = alloc::vec![&(*TICK_ACTIVITY), &STDIN.pushed, &(*SOCKET_ACTIVITY)];
let polls = unsafe { self.vm().check_write_array(ufds, nfds)? };
for poll in polls.iter() {
match proc.files.get(&(poll.fd as usize)){
None => {
return Err(SysError::EINVAL);
},
Some(file_like) => {
// file_like.poll_condvar(&mut condvars);
}
}
}
drop(proc);
let begin_time_ms = crate::trap::uptime_msec();
@ -206,10 +198,7 @@ impl Syscall<'_> {
1 << 31
};
let mut condvars = Vec::new();
condvars.push(&(*TICK_ACTIVITY));
condvars.push(&STDIN.pushed);
condvars.push(&(*SOCKET_ACTIVITY));
let mut condvars = alloc::vec![&(*TICK_ACTIVITY), &STDIN.pushed, &(*SOCKET_ACTIVITY)];
// for debugging
if cfg!(debug_assertions) {
@ -277,7 +266,7 @@ impl Syscall<'_> {
return Err(SysError::EINVAL);
}
return self.sys_epoll_create1(0);
self.sys_epoll_create1(0)
}
@ -306,20 +295,20 @@ impl Syscall<'_> {
info!("sys_epoll_ctl: epfd: {}, op: {:?}, fd: {:#x}", epfd, op, fd);
}
let slice = unsafe { self.vm().check_read_array(event, 1)? };
let _event = unsafe { self.vm().check_read_ptr(event)? };
if proc.files.get(&fd).is_none(){
return Err(SysError::EPERM);
}
let epollInstance = match proc.get_epoll_instance(epfd) {
let epollInstance = match proc.get_epoll_instance_mut(epfd) {
Ok(ins) => ins,
Err(err) => {
return Err(err);
}
};
let ret = epollInstance.epoll_ctl(&self.vm(),op, fd, event)?;
let ret = epollInstance.control(op, fd, & _event)?;
return Ok(ret);
}
@ -344,8 +333,8 @@ impl Syscall<'_> {
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 events = unsafe { self.vm().check_write_array(events, maxevents)? };
let epollInstance = proc.get_epoll_instance(epfd)?;
// add new fds which are registered by epoll_ctl after latest epoll_pwait
epollInstance.readyList.lock().clear();
@ -365,9 +354,7 @@ impl Syscall<'_> {
let status = file_like.poll()?;
if status.write || status.read || status.error {
let mut readylist = epollInstance.readyList.lock();
if !readylist.contains(k) {
readylist.push_back(*k);
}
readylist.insert(*k);
}
}
}
@ -380,9 +367,6 @@ impl Syscall<'_> {
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) => {
@ -399,23 +383,20 @@ impl Syscall<'_> {
return Err(SysError::EINVAL);
}
};
}
},
None => {},
}
drop(proc);
}
let mut condvars = Vec::new();
condvars.push(&(*TICK_ACTIVITY));
condvars.push(&STDIN.pushed);
condvars.push(&(*SOCKET_ACTIVITY));
let mut condvars = alloc::vec![&(*TICK_ACTIVITY), &STDIN.pushed, &(*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) {
let epollInstance = match proc.get_epoll_instance_mut(epfd) {
Ok(ins) => ins,
Err(err) => {
return Some(Err(err));
@ -427,8 +408,7 @@ impl Syscall<'_> {
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();
if let Some(file_like) = proc.files.get(&infd) {
let _status = match file_like.poll() {
Ok(ret) => ret,
Err(err) => return Some(Err(err)),
@ -440,7 +420,7 @@ impl Syscall<'_> {
}
{
let epollInstance = match proc.get_epoll_instance(epfd) {
let epollInstance = match proc.get_epoll_instance_mut(epfd) {
Ok(ins) => ins,
Err(err) => {
return Some(Err(err));
@ -449,41 +429,33 @@ impl Syscall<'_> {
let epollevent = epollInstance.events.get_mut(&infd)?;
if status.error {
unsafe {
let _ = epollevent.copy_result_to(EpollEvent::EPOLLERR, &self.vm(), events, events_num);
}
events[events_num].events = EpollEvent::EPOLLERR;
events[events_num].data = epollevent.data;
events_num += 1;
}
if status.read && epollevent.contains(EpollEvent::EPOLLIN) {
unsafe {
let _ = epollevent.copy_result_to(EpollEvent::EPOLLIN, &self.vm(), events, events_num);
}
events[events_num].events = EpollEvent::EPOLLIN;
events[events_num].data = epollevent.data;
events_num += 1;
}
if status.write && epollevent.contains(EpollEvent::EPOLLOUT) {
unsafe {
let _ = epollevent.copy_result_to(EpollEvent::EPOLLOUT, &self.vm(), events, events_num);
}
events[events_num].events = EpollEvent::EPOLLOUT;
events[events_num].data = epollevent.data;
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) {
let epollInstance = match proc.get_epoll_instance_mut(epfd) {
Ok(ins) => ins,
Err(err) => {
return Some(Err(err));
}
};
let mut lock = epollInstance.readyList.lock();
lock.retain(|x| false);
epollInstance.readyList.lock().clear();
}
drop(proc);
@ -504,12 +476,11 @@ impl Syscall<'_> {
let num = Condvar::wait_events(condvars.as_slice(), condition).unwrap();
for cb in callbacks.iter(){
if cb.0 == 0 {
&crate::fs::STDIN.pushed.unregister_epoll_list(cb.1, cb.2, cb.3);
}
if cb.0 == 1 {
&(*crate::drivers::SOCKET_ACTIVITY).unregister_epoll_list(cb.1, cb.2, cb.3);
}
match cb.0 {
0 => &crate::fs::STDIN.pushed.unregister_epoll_list(cb.1, cb.2, cb.3),
1 => &(*crate::drivers::SOCKET_ACTIVITY).unregister_epoll_list(cb.1, cb.2, cb.3),
_ => panic!("cb error"),
};
}
Ok(num)
}
@ -1805,178 +1776,7 @@ impl FdSet {
}
//#[derive(Clone)]
pub struct EpollInstance {
pub events: BTreeMap<usize, EpollEvent>,
pub readyList: SpinNoIrqLock<VecDeque<usize>>,
pub newCtlList: SpinNoIrqLock<VecDeque<usize>>,
}
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(),
newCtlList: 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());
let mut l = self.newCtlList.lock();
if !l.contains(&fd) {
l.push_back(fd);
}
}
// } 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());
let mut l = self.newCtlList.lock();
if !l.contains(&fd) {
l.push_back(fd);
}
}
} 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,
}
#[repr(packed)]
#[derive(Clone)]
pub struct EpollEvent {
events: u32, /* Epoll events */
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;

View File

@ -15,7 +15,7 @@ use crate::process::*;
use crate::sync::{Condvar, MutexGuard, SpinNoIrq};
use crate::thread;
use crate::util;
use crate::syscall::{EpollEvent};
use crate::fs::epoll::EpollEvent;
pub use self::custom::*;
pub use self::fs::*;