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