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