1 use system_error::SystemError; 2 3 use crate::{ 4 mm::{verify_area, VirtAddr}, 5 syscall::Syscall, 6 time::TimeSpec, 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<TimeSpec>, 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