xref: /DragonOS/kernel/src/libs/futex/syscall.rs (revision 6fc066ac11d2f9a3ac629d57487a6144fda1ac63)
191e9d4abSLoGin use system_error::SystemError;
291e9d4abSLoGin 
306560afaShmt use crate::{
406560afaShmt     mm::{verify_area, VirtAddr},
506560afaShmt     syscall::Syscall,
6*6fc066acSJomo     time::PosixTimeSpec,
706560afaShmt };
8971462beSGnoCiYeH 
906560afaShmt use super::{
1006560afaShmt     constant::*,
1106560afaShmt     futex::{Futex, RobustListHead},
1206560afaShmt };
13971462beSGnoCiYeH 
14971462beSGnoCiYeH impl Syscall {
do_futex( uaddr: VirtAddr, operation: FutexFlag, val: u32, timeout: Option<PosixTimeSpec>, uaddr2: VirtAddr, val2: u32, val3: u32, ) -> Result<usize, SystemError>15971462beSGnoCiYeH     pub fn do_futex(
16971462beSGnoCiYeH         uaddr: VirtAddr,
17971462beSGnoCiYeH         operation: FutexFlag,
18971462beSGnoCiYeH         val: u32,
19*6fc066acSJomo         timeout: Option<PosixTimeSpec>,
20971462beSGnoCiYeH         uaddr2: VirtAddr,
21971462beSGnoCiYeH         val2: u32,
22971462beSGnoCiYeH         val3: u32,
23971462beSGnoCiYeH     ) -> Result<usize, SystemError> {
2406560afaShmt         verify_area(uaddr, core::mem::size_of::<u32>())?;
2506560afaShmt         verify_area(uaddr2, core::mem::size_of::<u32>())?;
2606560afaShmt 
27971462beSGnoCiYeH         let cmd = FutexArg::from_bits(operation.bits() & FutexFlag::FUTEX_CMD_MASK.bits())
28971462beSGnoCiYeH             .ok_or(SystemError::ENOSYS)?;
29971462beSGnoCiYeH 
30971462beSGnoCiYeH         let mut flags = FutexFlag::FLAGS_MATCH_NONE;
31971462beSGnoCiYeH 
32971462beSGnoCiYeH         if !operation.contains(FutexFlag::FUTEX_PRIVATE_FLAG) {
33971462beSGnoCiYeH             flags.insert(FutexFlag::FLAGS_SHARED);
34971462beSGnoCiYeH         }
35971462beSGnoCiYeH 
36971462beSGnoCiYeH         if operation.contains(FutexFlag::FUTEX_CLOCK_REALTIME) {
37971462beSGnoCiYeH             flags.insert(FutexFlag::FLAGS_CLOCKRT);
38971462beSGnoCiYeH             if cmd != FutexArg::FUTEX_WAIT_BITSET
39971462beSGnoCiYeH                 && cmd != FutexArg::FUTEX_WAIT_REQUEUE_PI
40971462beSGnoCiYeH                 && cmd != FutexArg::FUTEX_LOCK_PI2
41971462beSGnoCiYeH             {
42971462beSGnoCiYeH                 return Err(SystemError::ENOSYS);
43971462beSGnoCiYeH             }
44971462beSGnoCiYeH         }
45971462beSGnoCiYeH 
46971462beSGnoCiYeH         match cmd {
47971462beSGnoCiYeH             FutexArg::FUTEX_WAIT => {
48971462beSGnoCiYeH                 return Futex::futex_wait(uaddr, flags, val, timeout, FUTEX_BITSET_MATCH_ANY);
49971462beSGnoCiYeH             }
50971462beSGnoCiYeH             FutexArg::FUTEX_WAIT_BITSET => {
51971462beSGnoCiYeH                 return Futex::futex_wait(uaddr, flags, val, timeout, val3);
52971462beSGnoCiYeH             }
53971462beSGnoCiYeH             FutexArg::FUTEX_WAKE => {
54971462beSGnoCiYeH                 return Futex::futex_wake(uaddr, flags, val, FUTEX_BITSET_MATCH_ANY);
55971462beSGnoCiYeH             }
56971462beSGnoCiYeH             FutexArg::FUTEX_WAKE_BITSET => {
57971462beSGnoCiYeH                 return Futex::futex_wake(uaddr, flags, val, val3);
58971462beSGnoCiYeH             }
59971462beSGnoCiYeH             FutexArg::FUTEX_REQUEUE => {
60971462beSGnoCiYeH                 return Futex::futex_requeue(
61971462beSGnoCiYeH                     uaddr,
62971462beSGnoCiYeH                     flags,
63971462beSGnoCiYeH                     uaddr2,
64971462beSGnoCiYeH                     val as i32,
65971462beSGnoCiYeH                     val2 as i32,
66971462beSGnoCiYeH                     None,
67971462beSGnoCiYeH                     false,
68971462beSGnoCiYeH                 );
69971462beSGnoCiYeH             }
70971462beSGnoCiYeH             FutexArg::FUTEX_CMP_REQUEUE => {
71971462beSGnoCiYeH                 return Futex::futex_requeue(
72971462beSGnoCiYeH                     uaddr,
73971462beSGnoCiYeH                     flags,
74971462beSGnoCiYeH                     uaddr2,
75971462beSGnoCiYeH                     val as i32,
76971462beSGnoCiYeH                     val2 as i32,
77971462beSGnoCiYeH                     Some(val3),
78971462beSGnoCiYeH                     false,
79971462beSGnoCiYeH                 );
80971462beSGnoCiYeH             }
81971462beSGnoCiYeH             FutexArg::FUTEX_WAKE_OP => {
82971462beSGnoCiYeH                 return Futex::futex_wake_op(
83971462beSGnoCiYeH                     uaddr,
84971462beSGnoCiYeH                     flags,
85971462beSGnoCiYeH                     uaddr2,
86971462beSGnoCiYeH                     val as i32,
87971462beSGnoCiYeH                     val2 as i32,
88971462beSGnoCiYeH                     val3 as i32,
89971462beSGnoCiYeH                 );
90971462beSGnoCiYeH             }
91971462beSGnoCiYeH             FutexArg::FUTEX_LOCK_PI => {
92971462beSGnoCiYeH                 todo!()
93971462beSGnoCiYeH             }
94971462beSGnoCiYeH             FutexArg::FUTEX_LOCK_PI2 => {
95971462beSGnoCiYeH                 todo!()
96971462beSGnoCiYeH             }
97971462beSGnoCiYeH             FutexArg::FUTEX_UNLOCK_PI => {
98971462beSGnoCiYeH                 todo!()
99971462beSGnoCiYeH             }
100971462beSGnoCiYeH             FutexArg::FUTEX_TRYLOCK_PI => {
101971462beSGnoCiYeH                 todo!()
102971462beSGnoCiYeH             }
103971462beSGnoCiYeH             FutexArg::FUTEX_WAIT_REQUEUE_PI => {
104971462beSGnoCiYeH                 todo!()
105971462beSGnoCiYeH             }
106971462beSGnoCiYeH             FutexArg::FUTEX_CMP_REQUEUE_PI => {
107971462beSGnoCiYeH                 todo!()
108971462beSGnoCiYeH             }
109971462beSGnoCiYeH             _ => {
110971462beSGnoCiYeH                 return Err(SystemError::ENOSYS);
111971462beSGnoCiYeH             }
112971462beSGnoCiYeH         }
113971462beSGnoCiYeH     }
11406560afaShmt 
set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError>11506560afaShmt     pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
11606560afaShmt         //判断用户空间地址的合法性
11706560afaShmt         verify_area(head_uaddr, core::mem::size_of::<u32>())?;
11806560afaShmt 
11906560afaShmt         let ret = RobustListHead::set_robust_list(head_uaddr, len);
12006560afaShmt         return ret;
12106560afaShmt     }
12206560afaShmt 
get_robust_list( pid: usize, head_uaddr: VirtAddr, len_ptr_uaddr: VirtAddr, ) -> Result<usize, SystemError>12306560afaShmt     pub fn get_robust_list(
12406560afaShmt         pid: usize,
12506560afaShmt         head_uaddr: VirtAddr,
12606560afaShmt         len_ptr_uaddr: VirtAddr,
12706560afaShmt     ) -> Result<usize, SystemError> {
12806560afaShmt         //判断用户空间地址的合法性
12906560afaShmt         verify_area(head_uaddr, core::mem::size_of::<u32>())?;
13006560afaShmt         verify_area(len_ptr_uaddr, core::mem::size_of::<u32>())?;
13106560afaShmt 
13206560afaShmt         let ret = RobustListHead::get_robust_list(pid, head_uaddr, len_ptr_uaddr);
13306560afaShmt         return ret;
13406560afaShmt     }
135971462beSGnoCiYeH }
136