1 use crate::filesystem::vfs::file::{File, FileMode}; 2 use crate::filesystem::vfs::syscall::ModeType; 3 use crate::filesystem::vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata}; 4 use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 5 use crate::libs::wait_queue::WaitQueue; 6 use crate::net::event_poll::{EPollEventType, EPollItem, EventPoll, KernelIoctlData}; 7 use crate::process::ProcessManager; 8 use crate::syscall::Syscall; 9 use alloc::collections::LinkedList; 10 use alloc::string::String; 11 use alloc::sync::Arc; 12 use alloc::sync::Weak; 13 use alloc::vec::Vec; 14 use core::any::Any; 15 use ida::IdAllocator; 16 use system_error::SystemError; 17 18 static EVENTFD_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, u32::MAX as usize); 19 20 bitflags! { 21 pub struct EventFdFlags: u32{ 22 /// Provide semaphore-like semantics for reads from the new 23 /// file descriptor. 24 const EFD_SEMAPHORE = 0o1; 25 /// Set the close-on-exec (FD_CLOEXEC) flag on the new file 26 /// descriptor 27 const EFD_CLOEXEC = 0o2000000; 28 /// Set the O_NONBLOCK file status flag on the open file 29 /// description (see open(2)) referred to by the new file 30 /// descriptor 31 const EFD_NONBLOCK = 0o0004000; 32 } 33 } 34 35 #[derive(Debug)] 36 pub struct EventFd { 37 count: u64, 38 flags: EventFdFlags, 39 #[allow(unused)] 40 id: u32, 41 } 42 43 impl EventFd { 44 pub fn new(count: u64, flags: EventFdFlags, id: u32) -> Self { 45 EventFd { count, flags, id } 46 } 47 } 48 49 #[derive(Debug)] 50 pub struct EventFdInode { 51 eventfd: SpinLock<EventFd>, 52 wait_queue: WaitQueue, 53 epitems: SpinLock<LinkedList<Arc<EPollItem>>>, 54 } 55 56 impl EventFdInode { 57 pub fn new(eventfd: EventFd) -> Self { 58 EventFdInode { 59 eventfd: SpinLock::new(eventfd), 60 wait_queue: WaitQueue::default(), 61 epitems: SpinLock::new(LinkedList::new()), 62 } 63 } 64 pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> { 65 let is_remove = !self 66 .epitems 67 .lock_irqsave() 68 .extract_if(|x| x.epoll().ptr_eq(epoll)) 69 .collect::<Vec<_>>() 70 .is_empty(); 71 72 if is_remove { 73 return Ok(()); 74 } 75 76 Err(SystemError::ENOENT) 77 } 78 } 79 80 impl IndexNode for EventFdInode { 81 fn open( 82 &self, 83 _data: SpinLockGuard<FilePrivateData>, 84 _mode: &FileMode, 85 ) -> Result<(), SystemError> { 86 Ok(()) 87 } 88 89 fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 90 Ok(()) 91 } 92 93 /// # 从 counter 里读取一个 8 字节的int值 94 /// 95 /// 1. counter !=0 96 /// - EFD_SEMAPHORE 如果没有被设置,从 eventfd read,会得到 counter,并将它归0 97 /// - EFD_SEMAPHORE 如果被设置,从 eventfd read,会得到值 1,并将 counter - 1 98 /// 2. counter == 0 99 /// - EFD_NONBLOCK 如果被设置,那么会以 EAGAIN 的错失败 100 /// - 否则 read 会被阻塞,直到为非0。 101 fn read_at( 102 &self, 103 _offset: usize, 104 len: usize, 105 buf: &mut [u8], 106 data: SpinLockGuard<FilePrivateData>, 107 ) -> Result<usize, SystemError> { 108 if len < 8 { 109 return Err(SystemError::EINVAL); 110 } 111 let mut val = loop { 112 let val = self.eventfd.lock().count; 113 if val != 0 { 114 break val; 115 } 116 if self 117 .eventfd 118 .lock() 119 .flags 120 .contains(EventFdFlags::EFD_NONBLOCK) 121 { 122 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 123 } 124 self.wait_queue.sleep(); 125 }; 126 127 let mut eventfd = self.eventfd.lock(); 128 if eventfd.flags.contains(EventFdFlags::EFD_SEMAPHORE) { 129 eventfd.count -= 1; 130 val = 1; 131 } else { 132 eventfd.count = 0; 133 } 134 let val_bytes = val.to_ne_bytes(); 135 buf[..8].copy_from_slice(&val_bytes); 136 137 let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32); 138 // 唤醒epoll中等待的进程 139 EventPoll::wakeup_epoll(&self.epitems, pollflag)?; 140 141 return Ok(8); 142 } 143 144 /// # 把一个 8 字节的int值写入到 counter 里 145 /// 146 /// - counter 最大值是 2^64 - 1 147 /// - 如果写入时会发生溢出,则write会被阻塞 148 /// - 如果 EFD_NONBLOCK 被设置,那么以 EAGAIN 失败 149 /// - 以不合法的值写入时,会以 EINVAL 失败 150 /// - 比如 0xffffffffffffffff 不合法 151 /// - 比如 写入的值 size 小于8字节 152 fn write_at( 153 &self, 154 _offset: usize, 155 len: usize, 156 buf: &[u8], 157 data: SpinLockGuard<FilePrivateData>, 158 ) -> Result<usize, SystemError> { 159 if len < 8 { 160 return Err(SystemError::EINVAL); 161 } 162 let val = u64::from_ne_bytes(buf[..8].try_into().unwrap()); 163 if val == u64::MAX { 164 return Err(SystemError::EINVAL); 165 } 166 loop { 167 let eventfd = self.eventfd.lock(); 168 if u64::MAX - eventfd.count > val { 169 break; 170 } 171 // block until a read() is performed on the 172 // file descriptor, or fails with the error EAGAIN if the 173 // file descriptor has been made nonblocking. 174 if eventfd.flags.contains(EventFdFlags::EFD_NONBLOCK) { 175 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 176 } 177 drop(eventfd); 178 self.wait_queue.sleep(); 179 } 180 let mut eventfd = self.eventfd.lock(); 181 eventfd.count += val; 182 self.wait_queue.wakeup_all(None); 183 184 let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32); 185 // 唤醒epoll中等待的进程 186 EventPoll::wakeup_epoll(&self.epitems, pollflag)?; 187 return Ok(8); 188 } 189 190 /// # 检查 eventfd 的状态 191 /// 192 /// - 如果 counter 的值大于 0 ,那么 fd 的状态就是可读的 193 /// - 如果能无阻塞地写入一个至少为 1 的值,那么 fd 的状态就是可写的 194 fn poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> { 195 let mut events = EPollEventType::empty(); 196 if self.eventfd.lock().count != 0 { 197 events |= EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM; 198 } 199 if self.eventfd.lock().count != u64::MAX { 200 events |= EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM; 201 } 202 return Ok(events.bits() as usize); 203 } 204 205 fn metadata(&self) -> Result<Metadata, SystemError> { 206 let meta = Metadata { 207 mode: ModeType::from_bits_truncate(0o755), 208 file_type: FileType::File, 209 ..Default::default() 210 }; 211 Ok(meta) 212 } 213 214 fn resize(&self, _len: usize) -> Result<(), SystemError> { 215 Ok(()) 216 } 217 fn kernel_ioctl( 218 &self, 219 arg: Arc<dyn KernelIoctlData>, 220 _data: &FilePrivateData, 221 ) -> Result<usize, SystemError> { 222 let epitem = arg 223 .arc_any() 224 .downcast::<EPollItem>() 225 .map_err(|_| SystemError::EFAULT)?; 226 self.epitems.lock().push_back(epitem); 227 Ok(0) 228 } 229 fn fs(&self) -> Arc<dyn FileSystem> { 230 panic!("EventFd does not have a filesystem") 231 } 232 fn as_any_ref(&self) -> &dyn Any { 233 self 234 } 235 fn list(&self) -> Result<Vec<String>, SystemError> { 236 Err(SystemError::EINVAL) 237 } 238 } 239 240 impl Syscall { 241 /// # 创建一个 eventfd 文件描述符 242 /// 243 /// ## 参数 244 /// - `init_val`: u32: eventfd 的初始值 245 /// - `flags`: u32: eventfd 的标志 246 /// 247 /// ## 返回值 248 /// - `Ok(usize)`: 成功创建的文件描述符 249 /// - `Err(SystemError)`: 创建失败 250 /// 251 /// See: https://man7.org/linux/man-pages/man2/eventfd2.2.html 252 pub fn sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError> { 253 let flags = EventFdFlags::from_bits(flags).ok_or(SystemError::EINVAL)?; 254 let id = EVENTFD_ID_ALLOCATOR.alloc().ok_or(SystemError::ENOMEM)? as u32; 255 let eventfd = EventFd::new(init_val as u64, flags, id); 256 let inode = Arc::new(EventFdInode::new(eventfd)); 257 let filemode = if flags.contains(EventFdFlags::EFD_CLOEXEC) { 258 FileMode::O_RDWR | FileMode::O_CLOEXEC 259 } else { 260 FileMode::O_RDWR 261 }; 262 let file = File::new(inode, filemode)?; 263 let binding = ProcessManager::current_pcb().fd_table(); 264 let mut fd_table_guard = binding.write(); 265 let fd = fd_table_guard.alloc_fd(file, None).map(|x| x as usize); 266 return fd; 267 } 268 } 269