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