eventfd.rs 9.1 KB

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