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