123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893 |
- use core::{
- any::Any,
- fmt::Debug,
- sync::atomic::{AtomicBool, Ordering},
- };
- use alloc::{
- collections::LinkedList,
- sync::{Arc, Weak},
- vec::Vec,
- };
- use intertrait::CastFromSync;
- use system_error::SystemError;
- use crate::{
- filesystem::vfs::{
- file::{File, FileMode},
- FilePrivateData, IndexNode, Metadata,
- },
- libs::{
- rbtree::RBTree,
- rwlock::RwLock,
- spinlock::{SpinLock, SpinLockGuard},
- wait_queue::WaitQueue,
- },
- process::ProcessManager,
- sched::{schedule, SchedMode},
- time::{
- timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
- PosixTimeSpec,
- },
- };
- pub mod syscall;
- #[derive(Debug, Clone)]
- pub struct LockedEventPoll(Arc<SpinLock<EventPoll>>);
- #[derive(Debug)]
- pub struct EventPoll {
-
- epoll_wq: WaitQueue,
-
- ep_items: RBTree<i32, Arc<EPollItem>>,
-
- ready_list: LinkedList<Arc<EPollItem>>,
-
- shutdown: AtomicBool,
- self_ref: Option<Weak<SpinLock<EventPoll>>>,
- }
- impl EventPoll {
- pub const EP_MAX_EVENTS: u32 = u32::MAX / (core::mem::size_of::<EPollEvent>() as u32);
-
- pub const ADD_EPOLLITEM: u32 = 0x7965;
- pub fn new() -> Self {
- Self {
- epoll_wq: WaitQueue::default(),
- ep_items: RBTree::new(),
- ready_list: LinkedList::new(),
- shutdown: AtomicBool::new(false),
- self_ref: None,
- }
- }
- }
- impl Default for EventPoll {
- fn default() -> Self {
- Self::new()
- }
- }
- #[derive(Debug)]
- pub struct EPollItem {
-
- 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
- }
-
- 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();
- }
- }
- pub trait KernelIoctlData: Send + Sync + Any + Debug + CastFromSync {}
- impl KernelIoctlData for EPollItem {}
- #[derive(Debug, Clone)]
- pub struct EPollPrivateData {
- epoll: LockedEventPoll,
- }
- #[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 poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> {
-
- todo!()
- }
- 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.shutdown.store(true, Ordering::SeqCst);
- epoll.ep_wake_all();
- let fds = epoll.ep_items.keys().cloned().collect::<Vec<_>>();
-
- for fd in fds {
- let file = ProcessManager::current_pcb()
- .fd_table()
- .read()
- .get_file_by_fd(fd);
- if file.is_some() {
- file.unwrap().remove_epoll(&Arc::downgrade(&self.epoll.0))?;
- }
- epoll.ep_items.remove(&fd);
- }
- Ok(())
- }
- fn open(
- &self,
- _data: SpinLockGuard<FilePrivateData>,
- _mode: &FileMode,
- ) -> Result<(), SystemError> {
- Ok(())
- }
- }
- impl EventPoll {
-
-
-
-
-
-
-
- pub fn do_create_epoll(flags: FileMode) -> Result<usize, SystemError> {
- if !flags.difference(FileMode::O_CLOEXEC).is_empty() {
- return Err(SystemError::EINVAL);
- }
-
- let epoll = LockedEventPoll(Arc::new(SpinLock::new(EventPoll::new())));
- epoll.0.lock_irqsave().self_ref = Some(Arc::downgrade(&epoll.0));
-
- let epoll_inode = EPollInode::new(epoll.clone());
- let mut ep_file = File::new(
- epoll_inode,
- FileMode::O_RDWR | (flags & FileMode::O_CLOEXEC),
- )?;
-
- ep_file.private_data = SpinLock::new(FilePrivateData::EPoll(EPollPrivateData { epoll }));
- let current_pcb = ProcessManager::current_pcb();
- let fd_table = current_pcb.fd_table();
- let mut fd_table_guard = fd_table.write();
- let fd = fd_table_guard.alloc_fd(ep_file, None)?;
- Ok(fd as usize)
- }
-
-
-
-
-
-
-
-
-
-
- pub fn do_epoll_ctl(
- epfd: i32,
- op: EPollCtlOption,
- fd: i32,
- epds: &mut EPollEvent,
- nonblock: bool,
- ) -> Result<usize, SystemError> {
- let current_pcb = ProcessManager::current_pcb();
- let fd_table = current_pcb.fd_table();
- let fd_table_guard = fd_table.read();
-
- let ep_file = fd_table_guard
- .get_file_by_fd(epfd)
- .ok_or(SystemError::EBADF)?;
- let dst_file = fd_table_guard
- .get_file_by_fd(fd)
- .ok_or(SystemError::EBADF)?;
-
- if op != EPollCtlOption::Del {
- epds.events &= !EPollEventType::EPOLLWAKEUP.bits();
- }
- let events = EPollEventType::from_bits_truncate(epds.events);
-
-
-
- if Arc::ptr_eq(&ep_file, &dst_file) || !Self::is_epoll_file(&ep_file) {
- return Err(SystemError::EINVAL);
- }
- if op != EPollCtlOption::Del && events.contains(EPollEventType::EPOLLEXCLUSIVE) {
-
- if op == EPollCtlOption::Mod {
- return Err(SystemError::EINVAL);
- }
-
- if op == EPollCtlOption::Add && Self::is_epoll_file(&dst_file)
- || !events
- .difference(EPollEventType::EPOLLEXCLUSIVE_OK_BITS)
- .is_empty()
- {
- return Err(SystemError::EINVAL);
- }
- }
-
- if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
- let mut epoll_guard = {
- if nonblock {
-
- if let Ok(guard) = epoll_data.epoll.0.try_lock_irqsave() {
- guard
- } else {
- return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
- }
- } else {
- epoll_data.epoll.0.lock_irqsave()
- }
- };
- if op == EPollCtlOption::Add {
-
-
-
- if Self::is_epoll_file(&dst_file) {
- todo!();
- }
- }
- let ep_item = epoll_guard.ep_items.get(&fd);
- match op {
- EPollCtlOption::Add => {
-
- if ep_item.is_some() {
- return Err(SystemError::EEXIST);
- }
-
- let epitem = Arc::new(EPollItem::new(
- Arc::downgrade(&epoll_data.epoll.0),
- *epds,
- fd,
- Arc::downgrade(&dst_file),
- ));
- Self::ep_insert(&mut epoll_guard, dst_file, epitem)?;
- }
- EPollCtlOption::Del => {
-
- if ep_item.is_none() {
- return Err(SystemError::ENOENT);
- }
-
- Self::ep_remove(&mut epoll_guard, fd, Some(dst_file))?;
- }
- EPollCtlOption::Mod => {
-
- if ep_item.is_none() {
- return Err(SystemError::ENOENT);
- }
- let ep_item = ep_item.unwrap().clone();
- if ep_item.event.read().events & EPollEventType::EPOLLEXCLUSIVE.bits() != 0 {
- epds.events |=
- EPollEventType::EPOLLERR.bits() | EPollEventType::EPOLLHUP.bits();
- Self::ep_modify(&mut epoll_guard, ep_item, epds)?;
- }
- }
- }
- }
- Ok(0)
- }
-
- pub fn do_epoll_wait(
- epfd: i32,
- epoll_event: &mut [EPollEvent],
- max_events: i32,
- timespec: Option<PosixTimeSpec>,
- ) -> Result<usize, SystemError> {
- let current_pcb = ProcessManager::current_pcb();
- let fd_table = current_pcb.fd_table();
- let fd_table_guard = fd_table.read();
-
- let ep_file = fd_table_guard
- .get_file_by_fd(epfd)
- .ok_or(SystemError::EBADF)?;
- drop(fd_table_guard);
-
- if !Self::is_epoll_file(&ep_file) {
- return Err(SystemError::EINVAL);
- }
-
- let mut epolldata = None;
- if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
- epolldata = Some(epoll_data.clone())
- }
- if let Some(epoll_data) = epolldata {
- let epoll = epoll_data.epoll.clone();
- let epoll_guard = epoll.0.lock_irqsave();
- let mut timeout = false;
- if let Some(timespec) = timespec {
- if !(timespec.tv_sec > 0 || timespec.tv_nsec > 0) {
-
- timeout = true;
- }
- }
-
- let mut available = epoll_guard.ep_events_available();
- drop(epoll_guard);
- loop {
- if available {
-
- return Self::ep_send_events(epoll.clone(), epoll_event, max_events);
- }
- if epoll.0.lock_irqsave().shutdown.load(Ordering::SeqCst) {
-
- return Err(SystemError::EBADF);
- }
-
- if timeout {
- return Ok(0);
- }
-
- available = {
- let mut ret = false;
- for _ in 0..50 {
- if let Ok(guard) = epoll.0.try_lock_irqsave() {
- if guard.ep_events_available() {
- ret = true;
- break;
- }
- }
- }
-
- if !ret {
- ret = epoll.0.lock_irqsave().ep_events_available();
- }
- ret
- };
- if available {
- continue;
- }
-
- if current_pcb.has_pending_signal_fast() {
- return Err(SystemError::ERESTARTSYS);
- }
-
-
- let mut timer = None;
- if let Some(timespec) = timespec {
- let handle = WakeUpHelper::new(current_pcb.clone());
- let jiffies = next_n_us_timer_jiffies(
- (timespec.tv_sec * 1000000 + timespec.tv_nsec / 1000) as u64,
- );
- let inner: Arc<Timer> = Timer::new(handle, jiffies);
- inner.activate();
- timer = Some(inner);
- }
- let guard = epoll.0.lock_irqsave();
-
-
- unsafe { guard.epoll_wq.sleep_without_schedule() }.inspect_err(|_| {
- if let Some(timer) = timer.as_ref() {
- timer.cancel();
- }
- })?;
- drop(guard);
- schedule(SchedMode::SM_NONE);
-
- available = epoll.0.lock_irqsave().ep_events_available();
- if let Some(timer) = timer {
- if timer.as_ref().timeout() {
-
- timeout = true;
- } else {
-
- timer.cancel();
- }
- }
- }
- } else {
- panic!("An epoll file does not have the corresponding private information");
- }
- }
-
-
-
-
-
-
- fn ep_send_events(
- epoll: LockedEventPoll,
- user_event: &mut [EPollEvent],
- max_events: i32,
- ) -> Result<usize, SystemError> {
- let mut ep_guard = epoll.0.lock_irqsave();
- let mut res: usize = 0;
-
-
- let mut push_back = Vec::new();
- while let Some(epitem) = ep_guard.ready_list.pop_front() {
- if res >= max_events as usize {
- push_back.push(epitem);
- break;
- }
- let ep_events = EPollEventType::from_bits_truncate(epitem.event.read().events);
-
- let revents = epitem.ep_item_poll();
- if revents.is_empty() {
- continue;
- }
-
- let event = EPollEvent {
- events: revents.bits,
- data: epitem.event.read().data,
- };
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- user_event[res] = event;
-
- res += 1;
-
- if ep_events.contains(EPollEventType::EPOLLONESHOT) {
- let mut event_writer = epitem.event.write();
- let new_event = event_writer.events & EPollEventType::EP_PRIVATE_BITS.bits;
- event_writer.set_events(new_event);
- } else if !ep_events.contains(EPollEventType::EPOLLET) {
- push_back.push(epitem);
- }
- }
- for item in push_back {
- ep_guard.ep_add_ready(item);
- }
- Ok(res)
- }
-
- fn is_epoll_file(file: &Arc<File>) -> bool {
- if let FilePrivateData::EPoll(_) = *file.private_data.lock() {
- return true;
- }
- return false;
- }
- fn ep_insert(
- epoll_guard: &mut SpinLockGuard<EventPoll>,
- dst_file: Arc<File>,
- epitem: Arc<EPollItem>,
- ) -> Result<(), SystemError> {
- if Self::is_epoll_file(&dst_file) {
- return Err(SystemError::ENOSYS);
-
- }
- let test_poll = dst_file.poll();
- if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP {
-
- return Err(SystemError::ENOSYS);
- }
- epoll_guard.ep_items.insert(epitem.fd, epitem.clone());
-
- let event = epitem.ep_item_poll();
- if !event.is_empty() {
-
- epoll_guard.ep_add_ready(epitem.clone());
- epoll_guard.ep_wake_one();
- }
-
-
- if epitem.event.read().events & EPollEventType::EPOLLWAKEUP.bits() != 0 {
- return Err(SystemError::ENOSYS);
- }
- dst_file.add_epoll(epitem.clone())?;
- Ok(())
- }
- pub fn ep_remove(
- epoll: &mut SpinLockGuard<EventPoll>,
- fd: i32,
- dst_file: Option<Arc<File>>,
- ) -> Result<(), SystemError> {
- if let Some(dst_file) = dst_file {
- dst_file.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
- }
- let epitem = epoll.ep_items.remove(&fd).unwrap();
- let _ = epoll
- .ready_list
- .extract_if(|item| Arc::ptr_eq(item, &epitem));
- Ok(())
- }
-
-
-
-
-
-
- fn ep_modify(
- epoll_guard: &mut SpinLockGuard<EventPoll>,
- epitem: Arc<EPollItem>,
- event: &EPollEvent,
- ) -> Result<(), SystemError> {
- let mut epi_event_guard = epitem.event.write();
-
- epi_event_guard.events = event.events;
- epi_event_guard.data = event.data;
- drop(epi_event_guard);
-
- let event = epitem.ep_item_poll();
- if !event.is_empty() {
- epoll_guard.ep_add_ready(epitem.clone());
- epoll_guard.ep_wake_one();
- }
-
- Ok(())
- }
-
- pub fn ep_events_available(&self) -> bool {
- !self.ready_list.is_empty()
- }
-
- pub fn ep_add_ready(&mut self, epitem: Arc<EPollItem>) {
- let ret = self.ready_list.iter().find(|epi| Arc::ptr_eq(epi, &epitem));
- if ret.is_none() {
- self.ready_list.push_back(epitem);
- }
- }
-
- pub fn ep_has_waiter(&self) -> bool {
- self.epoll_wq.len() != 0
- }
-
- pub fn ep_wake_all(&self) {
- self.epoll_wq.wakeup_all(None);
- }
-
- pub fn ep_wake_one(&self) {
- self.epoll_wq.wakeup(None);
- }
-
- pub fn wakeup_epoll(
- epitems: &SpinLock<LinkedList<Arc<EPollItem>>>,
- pollflags: Option<EPollEventType>,
- ) -> Result<(), SystemError> {
- let mut epitems_guard = epitems.try_lock_irqsave()?;
-
- if let Some(epitem) = epitems_guard.pop_front() {
- let pollflags = pollflags.unwrap_or({
- if let Some(file) = epitem.file.upgrade() {
- EPollEventType::from_bits_truncate(file.poll()? as u32)
- } else {
- EPollEventType::empty()
- }
- });
- if let Some(epoll) = epitem.epoll().upgrade() {
- let mut epoll_guard = epoll.try_lock()?;
- let binding = epitem.clone();
- let event_guard = binding.event().read();
- let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
-
- if !(ep_events
- .difference(EPollEventType::EP_PRIVATE_BITS)
- .is_empty()
- || pollflags.difference(ep_events).is_empty())
- {
-
-
- epoll_guard.ep_add_ready(epitem.clone());
- if epoll_guard.ep_has_waiter() {
- if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE)
- && !pollflags.contains(EPollEventType::POLLFREE)
- {
-
- epoll_guard.ep_wake_one();
- } else {
- epoll_guard.ep_wake_all();
- }
- }
- }
- epitems_guard.push_back(epitem);
- }
- }
- Ok(())
- }
- }
- #[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
- }
- }
- #[derive(Debug, PartialEq)]
- pub enum EPollCtlOption {
-
- Add,
-
- 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;
-
- const EPOLLRDNORM = 0x00000040;
-
- const EPOLLRDBAND = 0x00000080;
-
- const EPOLLWRNORM = 0x00000100;
-
- const EPOLLWRBAND = 0x00000200;
-
- const EPOLLMSG = 0x00000400;
-
- const EPOLLRDHUP = 0x00002000;
-
-
-
- const EPOLL_URING_WAKE = 1u32 << 27;
-
- const EPOLLEXCLUSIVE = 1u32 << 28;
-
- const EPOLLWAKEUP = 1u32 << 29;
-
- const EPOLLONESHOT = 1u32 << 30;
-
-
- 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;
-
- const POLLFREE = 0x4000;
-
- const EPOLL_LISTEN_CAN_ACCEPT = Self::EPOLLIN.bits | Self::EPOLLRDNORM.bits;
- }
- }
|