eventfd.rs 9.5 KB

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