xref: /DragonOS/kernel/src/filesystem/eventfd.rs (revision 4afc5b7b7bed743d18c058e4843dcbdb2f3ad751)
186ee1395Slinfeng use crate::filesystem::vfs::file::{File, FileMode};
286ee1395Slinfeng use crate::filesystem::vfs::syscall::ModeType;
386ee1395Slinfeng use crate::filesystem::vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata};
486ee1395Slinfeng use crate::libs::spinlock::{SpinLock, SpinLockGuard};
586ee1395Slinfeng use crate::libs::wait_queue::WaitQueue;
6*4afc5b7bSlinfeng use crate::net::event_poll::{EPollEventType, EPollItem, EventPoll, KernelIoctlData};
786ee1395Slinfeng use crate::process::ProcessManager;
886ee1395Slinfeng use crate::syscall::Syscall;
9*4afc5b7bSlinfeng use alloc::collections::LinkedList;
1086ee1395Slinfeng use alloc::string::String;
1186ee1395Slinfeng use alloc::sync::Arc;
12*4afc5b7bSlinfeng use alloc::sync::Weak;
1386ee1395Slinfeng use alloc::vec::Vec;
1486ee1395Slinfeng use core::any::Any;
1586ee1395Slinfeng use ida::IdAllocator;
1686ee1395Slinfeng use system_error::SystemError;
1786ee1395Slinfeng 
1886ee1395Slinfeng static EVENTFD_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, u32::MAX as usize);
1986ee1395Slinfeng 
2086ee1395Slinfeng bitflags! {
2186ee1395Slinfeng     pub struct EventFdFlags: u32{
2286ee1395Slinfeng         /// Provide semaphore-like semantics for reads from the new
2386ee1395Slinfeng         /// file descriptor.
24*4afc5b7bSlinfeng         const EFD_SEMAPHORE = 0o1;
2586ee1395Slinfeng         /// Set the close-on-exec (FD_CLOEXEC) flag on the new file
2686ee1395Slinfeng         /// descriptor
27*4afc5b7bSlinfeng         const EFD_CLOEXEC = 0o2000000;
2886ee1395Slinfeng         /// Set the O_NONBLOCK file status flag on the open file
2986ee1395Slinfeng         /// description (see open(2)) referred to by the new file
3086ee1395Slinfeng         /// descriptor
31*4afc5b7bSlinfeng         const EFD_NONBLOCK = 0o0004000;
3286ee1395Slinfeng     }
3386ee1395Slinfeng }
3486ee1395Slinfeng 
3586ee1395Slinfeng #[derive(Debug)]
3686ee1395Slinfeng pub struct EventFd {
3786ee1395Slinfeng     count: u64,
3886ee1395Slinfeng     flags: EventFdFlags,
3986ee1395Slinfeng     #[allow(unused)]
4086ee1395Slinfeng     id: u32,
4186ee1395Slinfeng }
4286ee1395Slinfeng 
4386ee1395Slinfeng impl EventFd {
new(count: u64, flags: EventFdFlags, id: u32) -> Self4486ee1395Slinfeng     pub fn new(count: u64, flags: EventFdFlags, id: u32) -> Self {
4586ee1395Slinfeng         EventFd { count, flags, id }
4686ee1395Slinfeng     }
4786ee1395Slinfeng }
4886ee1395Slinfeng 
4986ee1395Slinfeng #[derive(Debug)]
5086ee1395Slinfeng pub struct EventFdInode {
5186ee1395Slinfeng     eventfd: SpinLock<EventFd>,
5286ee1395Slinfeng     wait_queue: WaitQueue,
53*4afc5b7bSlinfeng     epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
5486ee1395Slinfeng }
5586ee1395Slinfeng 
5686ee1395Slinfeng impl EventFdInode {
new(eventfd: EventFd) -> Self5786ee1395Slinfeng     pub fn new(eventfd: EventFd) -> Self {
5886ee1395Slinfeng         EventFdInode {
5986ee1395Slinfeng             eventfd: SpinLock::new(eventfd),
6086ee1395Slinfeng             wait_queue: WaitQueue::default(),
61*4afc5b7bSlinfeng             epitems: SpinLock::new(LinkedList::new()),
6286ee1395Slinfeng         }
6386ee1395Slinfeng     }
remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError>64*4afc5b7bSlinfeng     pub fn remove_epoll(&self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
65*4afc5b7bSlinfeng         let is_remove = !self
66*4afc5b7bSlinfeng             .epitems
67*4afc5b7bSlinfeng             .lock_irqsave()
68*4afc5b7bSlinfeng             .extract_if(|x| x.epoll().ptr_eq(epoll))
69*4afc5b7bSlinfeng             .collect::<Vec<_>>()
70*4afc5b7bSlinfeng             .is_empty();
71*4afc5b7bSlinfeng 
72*4afc5b7bSlinfeng         if is_remove {
73*4afc5b7bSlinfeng             return Ok(());
74*4afc5b7bSlinfeng         }
75*4afc5b7bSlinfeng 
76*4afc5b7bSlinfeng         Err(SystemError::ENOENT)
77*4afc5b7bSlinfeng     }
7886ee1395Slinfeng }
7986ee1395Slinfeng 
8086ee1395Slinfeng impl IndexNode for EventFdInode {
open( &self, _data: SpinLockGuard<FilePrivateData>, _mode: &FileMode, ) -> Result<(), SystemError>8186ee1395Slinfeng     fn open(
8286ee1395Slinfeng         &self,
8386ee1395Slinfeng         _data: SpinLockGuard<FilePrivateData>,
8486ee1395Slinfeng         _mode: &FileMode,
8586ee1395Slinfeng     ) -> Result<(), SystemError> {
8686ee1395Slinfeng         Ok(())
8786ee1395Slinfeng     }
8886ee1395Slinfeng 
close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>8986ee1395Slinfeng     fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
9086ee1395Slinfeng         Ok(())
9186ee1395Slinfeng     }
9286ee1395Slinfeng 
9386ee1395Slinfeng     /// # 从 counter 里读取一个 8 字节的int值
9486ee1395Slinfeng     ///
9586ee1395Slinfeng     /// 1. counter !=0
9686ee1395Slinfeng     ///     - EFD_SEMAPHORE 如果没有被设置,从 eventfd read,会得到 counter,并将它归0
9786ee1395Slinfeng     ///     - EFD_SEMAPHORE 如果被设置,从 eventfd read,会得到值 1,并将 counter - 1
9886ee1395Slinfeng     /// 2. counter == 0
9986ee1395Slinfeng     ///     - EFD_NONBLOCK 如果被设置,那么会以 EAGAIN 的错失败
10086ee1395Slinfeng     ///     - 否则 read 会被阻塞,直到为非0。
read_at( &self, _offset: usize, len: usize, buf: &mut [u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>10186ee1395Slinfeng     fn read_at(
10286ee1395Slinfeng         &self,
10386ee1395Slinfeng         _offset: usize,
10486ee1395Slinfeng         len: usize,
10586ee1395Slinfeng         buf: &mut [u8],
106*4afc5b7bSlinfeng         data: SpinLockGuard<FilePrivateData>,
10786ee1395Slinfeng     ) -> Result<usize, SystemError> {
10886ee1395Slinfeng         if len < 8 {
10986ee1395Slinfeng             return Err(SystemError::EINVAL);
11086ee1395Slinfeng         }
11186ee1395Slinfeng         let mut val = loop {
11286ee1395Slinfeng             let val = self.eventfd.lock().count;
11386ee1395Slinfeng             if val != 0 {
11486ee1395Slinfeng                 break val;
11586ee1395Slinfeng             }
11686ee1395Slinfeng             if self
11786ee1395Slinfeng                 .eventfd
11886ee1395Slinfeng                 .lock()
11986ee1395Slinfeng                 .flags
12086ee1395Slinfeng                 .contains(EventFdFlags::EFD_NONBLOCK)
12186ee1395Slinfeng             {
12286ee1395Slinfeng                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
12386ee1395Slinfeng             }
12486ee1395Slinfeng             self.wait_queue.sleep();
12586ee1395Slinfeng         };
12686ee1395Slinfeng 
12786ee1395Slinfeng         let mut eventfd = self.eventfd.lock();
12886ee1395Slinfeng         if eventfd.flags.contains(EventFdFlags::EFD_SEMAPHORE) {
12986ee1395Slinfeng             eventfd.count -= 1;
13086ee1395Slinfeng             val = 1;
13186ee1395Slinfeng         } else {
13286ee1395Slinfeng             eventfd.count = 0;
13386ee1395Slinfeng         }
13486ee1395Slinfeng         let val_bytes = val.to_ne_bytes();
13586ee1395Slinfeng         buf[..8].copy_from_slice(&val_bytes);
136*4afc5b7bSlinfeng 
137*4afc5b7bSlinfeng         let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32);
138*4afc5b7bSlinfeng         // 唤醒epoll中等待的进程
139*4afc5b7bSlinfeng         EventPoll::wakeup_epoll(&self.epitems, pollflag)?;
140*4afc5b7bSlinfeng 
14186ee1395Slinfeng         return Ok(8);
14286ee1395Slinfeng     }
14386ee1395Slinfeng 
14486ee1395Slinfeng     /// # 把一个 8 字节的int值写入到 counter 里
14586ee1395Slinfeng     ///
14686ee1395Slinfeng     /// - counter 最大值是 2^64 - 1
14786ee1395Slinfeng     /// - 如果写入时会发生溢出,则write会被阻塞
14886ee1395Slinfeng     ///     - 如果 EFD_NONBLOCK 被设置,那么以 EAGAIN 失败
14986ee1395Slinfeng     /// - 以不合法的值写入时,会以 EINVAL 失败
15086ee1395Slinfeng     ///     - 比如 0xffffffffffffffff 不合法
15186ee1395Slinfeng     ///     -  比如 写入的值 size 小于8字节
write_at( &self, _offset: usize, len: usize, buf: &[u8], data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>15286ee1395Slinfeng     fn write_at(
15386ee1395Slinfeng         &self,
15486ee1395Slinfeng         _offset: usize,
15586ee1395Slinfeng         len: usize,
15686ee1395Slinfeng         buf: &[u8],
157*4afc5b7bSlinfeng         data: SpinLockGuard<FilePrivateData>,
15886ee1395Slinfeng     ) -> Result<usize, SystemError> {
15986ee1395Slinfeng         if len < 8 {
16086ee1395Slinfeng             return Err(SystemError::EINVAL);
16186ee1395Slinfeng         }
16286ee1395Slinfeng         let val = u64::from_ne_bytes(buf[..8].try_into().unwrap());
16386ee1395Slinfeng         if val == u64::MAX {
16486ee1395Slinfeng             return Err(SystemError::EINVAL);
16586ee1395Slinfeng         }
16686ee1395Slinfeng         loop {
16786ee1395Slinfeng             let eventfd = self.eventfd.lock();
16886ee1395Slinfeng             if u64::MAX - eventfd.count > val {
16986ee1395Slinfeng                 break;
17086ee1395Slinfeng             }
17186ee1395Slinfeng             // block until a read() is performed  on the
17286ee1395Slinfeng             // file descriptor, or fails with the error EAGAIN if the
17386ee1395Slinfeng             // file descriptor has been made nonblocking.
17486ee1395Slinfeng             if eventfd.flags.contains(EventFdFlags::EFD_NONBLOCK) {
17586ee1395Slinfeng                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
17686ee1395Slinfeng             }
17786ee1395Slinfeng             drop(eventfd);
17886ee1395Slinfeng             self.wait_queue.sleep();
17986ee1395Slinfeng         }
18086ee1395Slinfeng         let mut eventfd = self.eventfd.lock();
18186ee1395Slinfeng         eventfd.count += val;
18286ee1395Slinfeng         self.wait_queue.wakeup_all(None);
183*4afc5b7bSlinfeng 
184*4afc5b7bSlinfeng         let pollflag = EPollEventType::from_bits_truncate(self.poll(&data)? as u32);
185*4afc5b7bSlinfeng         // 唤醒epoll中等待的进程
186*4afc5b7bSlinfeng         EventPoll::wakeup_epoll(&self.epitems, pollflag)?;
18786ee1395Slinfeng         return Ok(8);
18886ee1395Slinfeng     }
18986ee1395Slinfeng 
19086ee1395Slinfeng     /// # 检查 eventfd 的状态
19186ee1395Slinfeng     ///
19286ee1395Slinfeng     /// - 如果 counter 的值大于 0 ,那么 fd 的状态就是可读的
19386ee1395Slinfeng     /// - 如果能无阻塞地写入一个至少为 1 的值,那么 fd 的状态就是可写的
poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError>19486ee1395Slinfeng     fn poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> {
19586ee1395Slinfeng         let mut events = EPollEventType::empty();
19686ee1395Slinfeng         if self.eventfd.lock().count != 0 {
19786ee1395Slinfeng             events |= EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM;
19886ee1395Slinfeng         }
19986ee1395Slinfeng         if self.eventfd.lock().count != u64::MAX {
20086ee1395Slinfeng             events |= EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM;
20186ee1395Slinfeng         }
20286ee1395Slinfeng         return Ok(events.bits() as usize);
20386ee1395Slinfeng     }
20486ee1395Slinfeng 
metadata(&self) -> Result<Metadata, SystemError>20586ee1395Slinfeng     fn metadata(&self) -> Result<Metadata, SystemError> {
20686ee1395Slinfeng         let meta = Metadata {
20786ee1395Slinfeng             mode: ModeType::from_bits_truncate(0o755),
20886ee1395Slinfeng             file_type: FileType::File,
20986ee1395Slinfeng             ..Default::default()
21086ee1395Slinfeng         };
21186ee1395Slinfeng         Ok(meta)
21286ee1395Slinfeng     }
21386ee1395Slinfeng 
resize(&self, _len: usize) -> Result<(), SystemError>21486ee1395Slinfeng     fn resize(&self, _len: usize) -> Result<(), SystemError> {
21586ee1395Slinfeng         Ok(())
21686ee1395Slinfeng     }
kernel_ioctl( &self, arg: Arc<dyn KernelIoctlData>, _data: &FilePrivateData, ) -> Result<usize, SystemError>217*4afc5b7bSlinfeng     fn kernel_ioctl(
218*4afc5b7bSlinfeng         &self,
219*4afc5b7bSlinfeng         arg: Arc<dyn KernelIoctlData>,
220*4afc5b7bSlinfeng         _data: &FilePrivateData,
221*4afc5b7bSlinfeng     ) -> Result<usize, SystemError> {
222*4afc5b7bSlinfeng         let epitem = arg
223*4afc5b7bSlinfeng             .arc_any()
224*4afc5b7bSlinfeng             .downcast::<EPollItem>()
225*4afc5b7bSlinfeng             .map_err(|_| SystemError::EFAULT)?;
226*4afc5b7bSlinfeng         self.epitems.lock().push_back(epitem);
227*4afc5b7bSlinfeng         Ok(0)
228*4afc5b7bSlinfeng     }
fs(&self) -> Arc<dyn FileSystem>22986ee1395Slinfeng     fn fs(&self) -> Arc<dyn FileSystem> {
23086ee1395Slinfeng         panic!("EventFd does not have a filesystem")
23186ee1395Slinfeng     }
as_any_ref(&self) -> &dyn Any23286ee1395Slinfeng     fn as_any_ref(&self) -> &dyn Any {
23386ee1395Slinfeng         self
23486ee1395Slinfeng     }
list(&self) -> Result<Vec<String>, SystemError>23586ee1395Slinfeng     fn list(&self) -> Result<Vec<String>, SystemError> {
23686ee1395Slinfeng         Err(SystemError::EINVAL)
23786ee1395Slinfeng     }
23886ee1395Slinfeng }
23986ee1395Slinfeng 
24086ee1395Slinfeng impl Syscall {
24186ee1395Slinfeng     /// # 创建一个 eventfd 文件描述符
24286ee1395Slinfeng     ///
24386ee1395Slinfeng     /// ## 参数
24486ee1395Slinfeng     /// - `init_val`: u32: eventfd 的初始值
24586ee1395Slinfeng     /// - `flags`: u32: eventfd 的标志
24686ee1395Slinfeng     ///
24786ee1395Slinfeng     /// ## 返回值
24886ee1395Slinfeng     /// - `Ok(usize)`: 成功创建的文件描述符
24986ee1395Slinfeng     /// - `Err(SystemError)`: 创建失败
25086ee1395Slinfeng     ///
25186ee1395Slinfeng     /// See: https://man7.org/linux/man-pages/man2/eventfd2.2.html
sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError>25286ee1395Slinfeng     pub fn sys_eventfd(init_val: u32, flags: u32) -> Result<usize, SystemError> {
25386ee1395Slinfeng         let flags = EventFdFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
25486ee1395Slinfeng         let id = EVENTFD_ID_ALLOCATOR.alloc().ok_or(SystemError::ENOMEM)? as u32;
25586ee1395Slinfeng         let eventfd = EventFd::new(init_val as u64, flags, id);
25686ee1395Slinfeng         let inode = Arc::new(EventFdInode::new(eventfd));
25786ee1395Slinfeng         let filemode = if flags.contains(EventFdFlags::EFD_CLOEXEC) {
25886ee1395Slinfeng             FileMode::O_RDWR | FileMode::O_CLOEXEC
25986ee1395Slinfeng         } else {
26086ee1395Slinfeng             FileMode::O_RDWR
26186ee1395Slinfeng         };
26286ee1395Slinfeng         let file = File::new(inode, filemode)?;
26386ee1395Slinfeng         let binding = ProcessManager::current_pcb().fd_table();
26486ee1395Slinfeng         let mut fd_table_guard = binding.write();
26586ee1395Slinfeng         let fd = fd_table_guard.alloc_fd(file, None).map(|x| x as usize);
26686ee1395Slinfeng         return fd;
26786ee1395Slinfeng     }
26886ee1395Slinfeng }
269