xref: /DragonOS/kernel/src/libs/futex/syscall.rs (revision 81294aa2e6b257f0de5e3c28c3f3c89798330836)
1 use system_error::SystemError;
2 
3 use crate::{mm::VirtAddr, syscall::Syscall, time::TimeSpec};
4 
5 use super::{constant::*, futex::Futex};
6 
7 impl Syscall {
8     pub fn do_futex(
9         uaddr: VirtAddr,
10         operation: FutexFlag,
11         val: u32,
12         timeout: Option<TimeSpec>,
13         uaddr2: VirtAddr,
14         val2: u32,
15         val3: u32,
16     ) -> Result<usize, SystemError> {
17         let cmd = FutexArg::from_bits(operation.bits() & FutexFlag::FUTEX_CMD_MASK.bits())
18             .ok_or(SystemError::ENOSYS)?;
19 
20         let mut flags = FutexFlag::FLAGS_MATCH_NONE;
21 
22         if !operation.contains(FutexFlag::FUTEX_PRIVATE_FLAG) {
23             flags.insert(FutexFlag::FLAGS_SHARED);
24         }
25 
26         if operation.contains(FutexFlag::FUTEX_CLOCK_REALTIME) {
27             flags.insert(FutexFlag::FLAGS_CLOCKRT);
28             if cmd != FutexArg::FUTEX_WAIT_BITSET
29                 && cmd != FutexArg::FUTEX_WAIT_REQUEUE_PI
30                 && cmd != FutexArg::FUTEX_LOCK_PI2
31             {
32                 return Err(SystemError::ENOSYS);
33             }
34         }
35 
36         match cmd {
37             FutexArg::FUTEX_WAIT => {
38                 return Futex::futex_wait(uaddr, flags, val, timeout, FUTEX_BITSET_MATCH_ANY);
39             }
40             FutexArg::FUTEX_WAIT_BITSET => {
41                 return Futex::futex_wait(uaddr, flags, val, timeout, val3);
42             }
43             FutexArg::FUTEX_WAKE => {
44                 return Futex::futex_wake(uaddr, flags, val, FUTEX_BITSET_MATCH_ANY);
45             }
46             FutexArg::FUTEX_WAKE_BITSET => {
47                 return Futex::futex_wake(uaddr, flags, val, val3);
48             }
49             FutexArg::FUTEX_REQUEUE => {
50                 return Futex::futex_requeue(
51                     uaddr,
52                     flags,
53                     uaddr2,
54                     val as i32,
55                     val2 as i32,
56                     None,
57                     false,
58                 );
59             }
60             FutexArg::FUTEX_CMP_REQUEUE => {
61                 return Futex::futex_requeue(
62                     uaddr,
63                     flags,
64                     uaddr2,
65                     val as i32,
66                     val2 as i32,
67                     Some(val3),
68                     false,
69                 );
70             }
71             FutexArg::FUTEX_WAKE_OP => {
72                 return Futex::futex_wake_op(
73                     uaddr,
74                     flags,
75                     uaddr2,
76                     val as i32,
77                     val2 as i32,
78                     val3 as i32,
79                 );
80             }
81             FutexArg::FUTEX_LOCK_PI => {
82                 todo!()
83             }
84             FutexArg::FUTEX_LOCK_PI2 => {
85                 todo!()
86             }
87             FutexArg::FUTEX_UNLOCK_PI => {
88                 todo!()
89             }
90             FutexArg::FUTEX_TRYLOCK_PI => {
91                 todo!()
92             }
93             FutexArg::FUTEX_WAIT_REQUEUE_PI => {
94                 todo!()
95             }
96             FutexArg::FUTEX_CMP_REQUEUE_PI => {
97                 todo!()
98             }
99             _ => {
100                 return Err(SystemError::ENOSYS);
101             }
102         }
103     }
104 }
105