xref: /DragonOS/kernel/src/libs/futex/syscall.rs (revision 013ffb708fab7760ea999c1edf462c69ac68f0ac)
1 use system_error::SystemError;
2 
3 use crate::{
4     mm::{verify_area, VirtAddr},
5     syscall::Syscall,
6     time::PosixTimeSpec,
7 };
8 
9 use super::{
10     constant::*,
11     futex::{Futex, RobustListHead},
12 };
13 
14 impl Syscall {
15     pub fn do_futex(
16         uaddr: VirtAddr,
17         operation: FutexFlag,
18         val: u32,
19         timeout: Option<PosixTimeSpec>,
20         uaddr2: VirtAddr,
21         val2: u32,
22         val3: u32,
23     ) -> Result<usize, SystemError> {
24         verify_area(uaddr, core::mem::size_of::<u32>())?;
25         verify_area(uaddr2, core::mem::size_of::<u32>())?;
26 
27         let cmd = FutexArg::from_bits(operation.bits() & FutexFlag::FUTEX_CMD_MASK.bits())
28             .ok_or(SystemError::ENOSYS)?;
29 
30         let mut flags = FutexFlag::FLAGS_MATCH_NONE;
31 
32         if !operation.contains(FutexFlag::FUTEX_PRIVATE_FLAG) {
33             flags.insert(FutexFlag::FLAGS_SHARED);
34         }
35 
36         if operation.contains(FutexFlag::FUTEX_CLOCK_REALTIME) {
37             flags.insert(FutexFlag::FLAGS_CLOCKRT);
38             if cmd != FutexArg::FUTEX_WAIT_BITSET
39                 && cmd != FutexArg::FUTEX_WAIT_REQUEUE_PI
40                 && cmd != FutexArg::FUTEX_LOCK_PI2
41             {
42                 return Err(SystemError::ENOSYS);
43             }
44         }
45 
46         match cmd {
47             FutexArg::FUTEX_WAIT => {
48                 return Futex::futex_wait(uaddr, flags, val, timeout, FUTEX_BITSET_MATCH_ANY);
49             }
50             FutexArg::FUTEX_WAIT_BITSET => {
51                 return Futex::futex_wait(uaddr, flags, val, timeout, val3);
52             }
53             FutexArg::FUTEX_WAKE => {
54                 return Futex::futex_wake(uaddr, flags, val, FUTEX_BITSET_MATCH_ANY);
55             }
56             FutexArg::FUTEX_WAKE_BITSET => {
57                 return Futex::futex_wake(uaddr, flags, val, val3);
58             }
59             FutexArg::FUTEX_REQUEUE => {
60                 return Futex::futex_requeue(
61                     uaddr,
62                     flags,
63                     uaddr2,
64                     val as i32,
65                     val2 as i32,
66                     None,
67                     false,
68                 );
69             }
70             FutexArg::FUTEX_CMP_REQUEUE => {
71                 return Futex::futex_requeue(
72                     uaddr,
73                     flags,
74                     uaddr2,
75                     val as i32,
76                     val2 as i32,
77                     Some(val3),
78                     false,
79                 );
80             }
81             FutexArg::FUTEX_WAKE_OP => {
82                 return Futex::futex_wake_op(
83                     uaddr,
84                     flags,
85                     uaddr2,
86                     val as i32,
87                     val2 as i32,
88                     val3 as i32,
89                 );
90             }
91             FutexArg::FUTEX_LOCK_PI => {
92                 todo!()
93             }
94             FutexArg::FUTEX_LOCK_PI2 => {
95                 todo!()
96             }
97             FutexArg::FUTEX_UNLOCK_PI => {
98                 todo!()
99             }
100             FutexArg::FUTEX_TRYLOCK_PI => {
101                 todo!()
102             }
103             FutexArg::FUTEX_WAIT_REQUEUE_PI => {
104                 todo!()
105             }
106             FutexArg::FUTEX_CMP_REQUEUE_PI => {
107                 todo!()
108             }
109             _ => {
110                 return Err(SystemError::ENOSYS);
111             }
112         }
113     }
114 
115     pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
116         //判断用户空间地址的合法性
117         verify_area(head_uaddr, core::mem::size_of::<u32>())?;
118 
119         let ret = RobustListHead::set_robust_list(head_uaddr, len);
120         return ret;
121     }
122 
123     pub fn get_robust_list(
124         pid: usize,
125         head_uaddr: VirtAddr,
126         len_ptr_uaddr: VirtAddr,
127     ) -> Result<usize, SystemError> {
128         //判断用户空间地址的合法性
129         verify_area(head_uaddr, core::mem::size_of::<u32>())?;
130         verify_area(len_ptr_uaddr, core::mem::size_of::<u32>())?;
131 
132         let ret = RobustListHead::get_robust_list(pid, head_uaddr, len_ptr_uaddr);
133         return ret;
134     }
135 }
136