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