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