186ee1395Slinfeng use crate::filesystem::vfs::file::{File, FileMode}; 286ee1395Slinfeng use crate::filesystem::vfs::syscall::ModeType; 386ee1395Slinfeng use crate::filesystem::vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata}; 486ee1395Slinfeng use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 586ee1395Slinfeng use crate::libs::wait_queue::WaitQueue; 6*4afc5b7bSlinfeng use crate::net::event_poll::{EPollEventType, EPollItem, EventPoll, KernelIoctlData}; 786ee1395Slinfeng use crate::process::ProcessManager; 886ee1395Slinfeng use crate::syscall::Syscall; 9*4afc5b7bSlinfeng use alloc::collections::LinkedList; 1086ee1395Slinfeng use alloc::string::String; 1186ee1395Slinfeng use alloc::sync::Arc; 12*4afc5b7bSlinfeng use alloc::sync::Weak; 1386ee1395Slinfeng use alloc::vec::Vec; 1486ee1395Slinfeng use core::any::Any; 1586ee1395Slinfeng use ida::IdAllocator; 1686ee1395Slinfeng use system_error::SystemError; 1786ee1395Slinfeng 1886ee1395Slinfeng static EVENTFD_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, u32::MAX as usize); 1986ee1395Slinfeng 2086ee1395Slinfeng bitflags! { 2186ee1395Slinfeng pub struct EventFdFlags: u32{ 2286ee1395Slinfeng /// Provide semaphore-like semantics for reads from the new 2386ee1395Slinfeng /// file descriptor. 24*4afc5b7bSlinfeng const EFD_SEMAPHORE = 0o1; 2586ee1395Slinfeng /// Set the close-on-exec (FD_CLOEXEC) flag on the new file 2686ee1395Slinfeng /// descriptor 27*4afc5b7bSlinfeng const EFD_CLOEXEC = 0o2000000; 2886ee1395Slinfeng /// Set the O_NONBLOCK file status flag on the open file 2986ee1395Slinfeng /// description (see open(2)) referred to by the new file 3086ee1395Slinfeng /// descriptor 31*4afc5b7bSlinfeng const EFD_NONBLOCK = 0o0004000; 3286ee1395Slinfeng } 3386ee1395Slinfeng } 3486ee1395Slinfeng 3586ee1395Slinfeng #[derive(Debug)] 3686ee1395Slinfeng pub struct EventFd { 3786ee1395Slinfeng count: u64, 3886ee1395Slinfeng flags: EventFdFlags, 3986ee1395Slinfeng #[allow(unused)] 4086ee1395Slinfeng id: u32, 4186ee1395Slinfeng } 4286ee1395Slinfeng 4386ee1395Slinfeng impl EventFd { new(count: u64, flags: EventFdFlags, id: u32) -> Self4486ee1395Slinfeng pub fn new(count: u64, flags: EventFdFlags, id: u32) -> Self { 4586ee1395Slinfeng EventFd { count, flags, id } 4686ee1395Slinfeng } 4786ee1395Slinfeng } 4886ee1395Slinfeng 4986ee1395Slinfeng #[derive(Debug)] 5086ee1395Slinfeng pub struct EventFdInode { 5186ee1395Slinfeng eventfd: SpinLock<EventFd>, 5286ee1395Slinfeng wait_queue: WaitQueue, 53*4afc5b7bSlinfeng epitems: SpinLock<LinkedList<Arc<EPollItem>>>, 5486ee1395Slinfeng } 5586ee1395Slinfeng 5686ee1395Slinfeng impl EventFdInode { new(eventfd: EventFd) -> Self5786ee1395Slinfeng pub fn new(eventfd: EventFd) -> Self { 5886ee1395Slinfeng EventFdInode { 5986ee1395Slinfeng eventfd: SpinLock::new(eventfd), 6086ee1395Slinfeng wait_queue: WaitQueue::default(), 61*4afc5b7bSlinfeng epitems: SpinLock::new(LinkedList::new()), 6286ee1395Slinfeng } 6386ee1395Slinfeng } remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError>64*4afc5b7bSlinfeng pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> { 65*4afc5b7bSlinfeng let is_remove = !self 66*4afc5b7bSlinfeng .epitems 67*4afc5b7bSlinfeng .lock_irqsave() 68*4afc5b7bSlinfeng .extract_if(|x| x.epoll().ptr_eq(epoll)) 69*4afc5b7bSlinfeng .collect::<Vec<_>>() 70*4afc5b7bSlinfeng .is_empty(); 71*4afc5b7bSlinfeng 72*4afc5b7bSlinfeng if is_remove { 73*4afc5b7bSlinfeng return Ok(()); 74*4afc5b7bSlinfeng } 75*4afc5b7bSlinfeng 76*4afc5b7bSlinfeng Err(SystemError::ENOENT) 77*4afc5b7bSlinfeng } 7886ee1395Slinfeng } 7986ee1395Slinfeng 8086ee1395Slinfeng impl IndexNode for EventFdInode { open( &self, _data: SpinLockGuard<FilePrivateData>, _mode: &FileMode, ) -> Result<(), SystemError>8186ee1395Slinfeng fn open( 8286ee1395Slinfeng &self, 8386ee1395Slinfeng _data: SpinLockGuard<FilePrivateData>, 8486ee1395Slinfeng _mode: &FileMode, 8586ee1395Slinfeng ) -> Result<(), SystemError> { 8686ee1395Slinfeng Ok(()) 8786ee1395Slinfeng } 8886ee1395Slinfeng close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>8986ee1395Slinfeng fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 9086ee1395Slinfeng Ok(()) 9186ee1395Slinfeng } 9286ee1395Slinfeng 9386ee1395Slinfeng /// # 从 counter 里读取一个 8 字节的int值 9486ee1395Slinfeng /// 9586ee1395Slinfeng /// 1. counter !=0 9686ee1395Slinfeng /// - EFD_SEMAPHORE 如果没有被设置,从 eventfd read,会得到 counter,并将它归0 9786ee1395Slinfeng /// - EFD_SEMAPHORE 如果被设置,从 eventfd read,会得到值 1,并将 counter - 1 9886ee1395Slinfeng /// 2. counter == 0 9986ee1395Slinfeng /// - EFD_NONBLOCK 如果被设置,那么会以 EAGAIN 的错失败 10086ee1395Slinfeng /// - 否则 read 会被阻塞,直到为非0。 read_at( &self, _offset: usize, len: usize, buf: &mut [u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>10186ee1395Slinfeng fn read_at( 10286ee1395Slinfeng &self, 10386ee1395Slinfeng _offset: usize, 10486ee1395Slinfeng len: usize, 10586ee1395Slinfeng buf: &mut [u8], 106*4afc5b7bSlinfeng data: SpinLockGuard<FilePrivateData>, 10786ee1395Slinfeng ) -> Result<usize, SystemError> { 10886ee1395Slinfeng if len < 8 { 10986ee1395Slinfeng return Err(SystemError::EINVAL); 11086ee1395Slinfeng } 11186ee1395Slinfeng let mut val = loop { 11286ee1395Slinfeng let val = self.eventfd.lock().count; 11386ee1395Slinfeng if val != 0 { 11486ee1395Slinfeng break val; 11586ee1395Slinfeng } 11686ee1395Slinfeng if self 11786ee1395Slinfeng .eventfd 11886ee1395Slinfeng .lock() 11986ee1395Slinfeng .flags 12086ee1395Slinfeng .contains(EventFdFlags::EFD_NONBLOCK) 12186ee1395Slinfeng { 12286ee1395Slinfeng return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 12386ee1395Slinfeng } 12486ee1395Slinfeng self.wait_queue.sleep(); 12586ee1395Slinfeng }; 12686ee1395Slinfeng 12786ee1395Slinfeng let mut eventfd = self.eventfd.lock(); 12886ee1395Slinfeng if eventfd.flags.contains(EventFdFlags::EFD_SEMAPHORE) { 12986ee1395Slinfeng eventfd.count -= 1; 13086ee1395Slinfeng val = 1; 13186ee1395Slinfeng } else { 13286ee1395Slinfeng eventfd.count = 0; 13386ee1395Slinfeng } 13486ee1395Slinfeng let val_bytes = val.to_ne_bytes(); 13586ee1395Slinfeng buf[..8].copy_from_slice(&val_bytes); 136*4afc5b7bSlinfeng 137*4afc5b7bSlinfeng let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32); 138*4afc5b7bSlinfeng // 唤醒epoll中等待的进程 139*4afc5b7bSlinfeng EventPoll::wakeup_epoll(&self.epitems, pollflag)?; 140*4afc5b7bSlinfeng 14186ee1395Slinfeng return Ok(8); 14286ee1395Slinfeng } 14386ee1395Slinfeng 14486ee1395Slinfeng /// # 把一个 8 字节的int值写入到 counter 里 14586ee1395Slinfeng /// 14686ee1395Slinfeng /// - counter 最大值是 2^64 - 1 14786ee1395Slinfeng /// - 如果写入时会发生溢出,则write会被阻塞 14886ee1395Slinfeng /// - 如果 EFD_NONBLOCK 被设置,那么以 EAGAIN 失败 14986ee1395Slinfeng /// - 以不合法的值写入时,会以 EINVAL 失败 15086ee1395Slinfeng /// - 比如 0xffffffffffffffff 不合法 15186ee1395Slinfeng /// - 比如 写入的值 size 小于8字节 write_at( &self, _offset: usize, len: usize, buf: &[u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>15286ee1395Slinfeng fn write_at( 15386ee1395Slinfeng &self, 15486ee1395Slinfeng _offset: usize, 15586ee1395Slinfeng len: usize, 15686ee1395Slinfeng buf: &[u8], 157*4afc5b7bSlinfeng data: SpinLockGuard<FilePrivateData>, 15886ee1395Slinfeng ) -> Result<usize, SystemError> { 15986ee1395Slinfeng if len < 8 { 16086ee1395Slinfeng return Err(SystemError::EINVAL); 16186ee1395Slinfeng } 16286ee1395Slinfeng let val = u64::from_ne_bytes(buf[..8].try_into().unwrap()); 16386ee1395Slinfeng if val == u64::MAX { 16486ee1395Slinfeng return Err(SystemError::EINVAL); 16586ee1395Slinfeng } 16686ee1395Slinfeng loop { 16786ee1395Slinfeng let eventfd = self.eventfd.lock(); 16886ee1395Slinfeng if u64::MAX - eventfd.count > val { 16986ee1395Slinfeng break; 17086ee1395Slinfeng } 17186ee1395Slinfeng // block until a read() is performed on the 17286ee1395Slinfeng // file descriptor, or fails with the error EAGAIN if the 17386ee1395Slinfeng // file descriptor has been made nonblocking. 17486ee1395Slinfeng if eventfd.flags.contains(EventFdFlags::EFD_NONBLOCK) { 17586ee1395Slinfeng return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 17686ee1395Slinfeng } 17786ee1395Slinfeng drop(eventfd); 17886ee1395Slinfeng self.wait_queue.sleep(); 17986ee1395Slinfeng } 18086ee1395Slinfeng let mut eventfd = self.eventfd.lock(); 18186ee1395Slinfeng eventfd.count += val; 18286ee1395Slinfeng self.wait_queue.wakeup_all(None); 183*4afc5b7bSlinfeng 184*4afc5b7bSlinfeng let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32); 185*4afc5b7bSlinfeng // 唤醒epoll中等待的进程 186*4afc5b7bSlinfeng EventPoll::wakeup_epoll(&self.epitems, pollflag)?; 18786ee1395Slinfeng return Ok(8); 18886ee1395Slinfeng } 18986ee1395Slinfeng 19086ee1395Slinfeng /// # 检查 eventfd 的状态 19186ee1395Slinfeng /// 19286ee1395Slinfeng /// - 如果 counter 的值大于 0 ,那么 fd 的状态就是可读的 19386ee1395Slinfeng /// - 如果能无阻塞地写入一个至少为 1 的值,那么 fd 的状态就是可写的 poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError>19486ee1395Slinfeng fn poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> { 19586ee1395Slinfeng let mut events = EPollEventType::empty(); 19686ee1395Slinfeng if self.eventfd.lock().count != 0 { 19786ee1395Slinfeng events |= EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM; 19886ee1395Slinfeng } 19986ee1395Slinfeng if self.eventfd.lock().count != u64::MAX { 20086ee1395Slinfeng events |= EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM; 20186ee1395Slinfeng } 20286ee1395Slinfeng return Ok(events.bits() as usize); 20386ee1395Slinfeng } 20486ee1395Slinfeng metadata(&self) -> Result<Metadata, SystemError>20586ee1395Slinfeng fn metadata(&self) -> Result<Metadata, SystemError> { 20686ee1395Slinfeng let meta = Metadata { 20786ee1395Slinfeng mode: ModeType::from_bits_truncate(0o755), 20886ee1395Slinfeng file_type: FileType::File, 20986ee1395Slinfeng ..Default::default() 21086ee1395Slinfeng }; 21186ee1395Slinfeng Ok(meta) 21286ee1395Slinfeng } 21386ee1395Slinfeng resize(&self, _len: usize) -> Result<(), SystemError>21486ee1395Slinfeng fn resize(&self, _len: usize) -> Result<(), SystemError> { 21586ee1395Slinfeng Ok(()) 21686ee1395Slinfeng } kernel_ioctl( &self, arg: Arc<dyn KernelIoctlData>, _data: &FilePrivateData, ) -> Result<usize, SystemError>217*4afc5b7bSlinfeng fn kernel_ioctl( 218*4afc5b7bSlinfeng &self, 219*4afc5b7bSlinfeng arg: Arc<dyn KernelIoctlData>, 220*4afc5b7bSlinfeng _data: &FilePrivateData, 221*4afc5b7bSlinfeng ) -> Result<usize, SystemError> { 222*4afc5b7bSlinfeng let epitem = arg 223*4afc5b7bSlinfeng .arc_any() 224*4afc5b7bSlinfeng .downcast::<EPollItem>() 225*4afc5b7bSlinfeng .map_err(|_| SystemError::EFAULT)?; 226*4afc5b7bSlinfeng self.epitems.lock().push_back(epitem); 227*4afc5b7bSlinfeng Ok(0) 228*4afc5b7bSlinfeng } fs(&self) -> Arc<dyn FileSystem>22986ee1395Slinfeng fn fs(&self) -> Arc<dyn FileSystem> { 23086ee1395Slinfeng panic!("EventFd does not have a filesystem") 23186ee1395Slinfeng } as_any_ref(&self) -> &dyn Any23286ee1395Slinfeng fn as_any_ref(&self) -> &dyn Any { 23386ee1395Slinfeng self 23486ee1395Slinfeng } list(&self) -> Result<Vec<String>, SystemError>23586ee1395Slinfeng fn list(&self) -> Result<Vec<String>, SystemError> { 23686ee1395Slinfeng Err(SystemError::EINVAL) 23786ee1395Slinfeng } 23886ee1395Slinfeng } 23986ee1395Slinfeng 24086ee1395Slinfeng impl Syscall { 24186ee1395Slinfeng /// # 创建一个 eventfd 文件描述符 24286ee1395Slinfeng /// 24386ee1395Slinfeng /// ## 参数 24486ee1395Slinfeng /// - `init_val`: u32: eventfd 的初始值 24586ee1395Slinfeng /// - `flags`: u32: eventfd 的标志 24686ee1395Slinfeng /// 24786ee1395Slinfeng /// ## 返回值 24886ee1395Slinfeng /// - `Ok(usize)`: 成功创建的文件描述符 24986ee1395Slinfeng /// - `Err(SystemError)`: 创建失败 25086ee1395Slinfeng /// 25186ee1395Slinfeng /// See: https://man7.org/linux/man-pages/man2/eventfd2.2.html sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError>25286ee1395Slinfeng pub fn sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError> { 25386ee1395Slinfeng let flags = EventFdFlags::from_bits(flags).ok_or(SystemError::EINVAL)?; 25486ee1395Slinfeng let id = EVENTFD_ID_ALLOCATOR.alloc().ok_or(SystemError::ENOMEM)? as u32; 25586ee1395Slinfeng let eventfd = EventFd::new(init_val as u64, flags, id); 25686ee1395Slinfeng let inode = Arc::new(EventFdInode::new(eventfd)); 25786ee1395Slinfeng let filemode = if flags.contains(EventFdFlags::EFD_CLOEXEC) { 25886ee1395Slinfeng FileMode::O_RDWR | FileMode::O_CLOEXEC 25986ee1395Slinfeng } else { 26086ee1395Slinfeng FileMode::O_RDWR 26186ee1395Slinfeng }; 26286ee1395Slinfeng let file = File::new(inode, filemode)?; 26386ee1395Slinfeng let binding = ProcessManager::current_pcb().fd_table(); 26486ee1395Slinfeng let mut fd_table_guard = binding.write(); 26586ee1395Slinfeng let fd = fd_table_guard.alloc_fd(file, None).map(|x| x as usize); 26686ee1395Slinfeng return fd; 26786ee1395Slinfeng } 26886ee1395Slinfeng } 269