1971462beSGnoCiYeH use alloc::{ 2971462beSGnoCiYeH collections::LinkedList, 3971462beSGnoCiYeH sync::{Arc, Weak}, 4971462beSGnoCiYeH }; 5971462beSGnoCiYeH use core::hash::{Hash, Hasher}; 606560afaShmt use core::{ 706560afaShmt intrinsics::{likely, unlikely}, 806560afaShmt mem, 906560afaShmt sync::atomic::AtomicU64, 1006560afaShmt }; 11*2eab6dd7S曾俊 use log::warn; 1206560afaShmt 13971462beSGnoCiYeH use hashbrown::HashMap; 1491e9d4abSLoGin use system_error::SystemError; 15971462beSGnoCiYeH 16971462beSGnoCiYeH use crate::{ 17f0c87a89SGnoCiYeH arch::{CurrentIrqArch, MMArch}, 18971462beSGnoCiYeH exception::InterruptArch, 19971462beSGnoCiYeH libs::spinlock::{SpinLock, SpinLockGuard}, 20971462beSGnoCiYeH mm::{ucontext::AddressSpace, MemoryManagementArch, VirtAddr}, 2106560afaShmt process::{Pid, ProcessControlBlock, ProcessManager}, 22f0c87a89SGnoCiYeH sched::{schedule, SchedMode}, 2306560afaShmt syscall::user_access::{UserBufferReader, UserBufferWriter}, 24971462beSGnoCiYeH time::{ 25971462beSGnoCiYeH timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper}, 266fc066acSJomo PosixTimeSpec, 27971462beSGnoCiYeH }, 28971462beSGnoCiYeH }; 29971462beSGnoCiYeH 30971462beSGnoCiYeH use super::constant::*; 31971462beSGnoCiYeH 32971462beSGnoCiYeH static mut FUTEX_DATA: Option<FutexData> = None; 33971462beSGnoCiYeH 34971462beSGnoCiYeH pub struct FutexData { 35971462beSGnoCiYeH data: SpinLock<HashMap<FutexKey, FutexHashBucket>>, 36971462beSGnoCiYeH } 37971462beSGnoCiYeH 38971462beSGnoCiYeH impl FutexData { futex_map() -> SpinLockGuard<'static, HashMap<FutexKey, FutexHashBucket>>39971462beSGnoCiYeH pub fn futex_map() -> SpinLockGuard<'static, HashMap<FutexKey, FutexHashBucket>> { 40971462beSGnoCiYeH unsafe { FUTEX_DATA.as_ref().unwrap().data.lock() } 41971462beSGnoCiYeH } 42971462beSGnoCiYeH try_remove(key: &FutexKey) -> Option<FutexHashBucket>43971462beSGnoCiYeH pub fn try_remove(key: &FutexKey) -> Option<FutexHashBucket> { 44971462beSGnoCiYeH unsafe { 45971462beSGnoCiYeH let mut guard = FUTEX_DATA.as_ref().unwrap().data.lock(); 46971462beSGnoCiYeH if let Some(futex) = guard.get(key) { 47971462beSGnoCiYeH if futex.chain.is_empty() { 48971462beSGnoCiYeH return guard.remove(key); 49971462beSGnoCiYeH } 50971462beSGnoCiYeH } 51971462beSGnoCiYeH } 52971462beSGnoCiYeH None 53971462beSGnoCiYeH } 54971462beSGnoCiYeH } 55971462beSGnoCiYeH 56971462beSGnoCiYeH pub struct Futex; 57971462beSGnoCiYeH 58971462beSGnoCiYeH // 对于同一个futex的进程或线程将会在这个bucket等待 59971462beSGnoCiYeH pub struct FutexHashBucket { 60971462beSGnoCiYeH // 该futex维护的等待队列 61971462beSGnoCiYeH chain: LinkedList<Arc<FutexObj>>, 62971462beSGnoCiYeH } 63971462beSGnoCiYeH 64971462beSGnoCiYeH impl FutexHashBucket { 65971462beSGnoCiYeH /// ## 判断是否在bucket里 contains(&self, futex_q: &FutexObj) -> bool66971462beSGnoCiYeH pub fn contains(&self, futex_q: &FutexObj) -> bool { 67971462beSGnoCiYeH self.chain 68971462beSGnoCiYeH .iter() 69971462beSGnoCiYeH .filter(|x| futex_q.pcb.ptr_eq(&x.pcb) && x.key == futex_q.key) 70971462beSGnoCiYeH .count() 71971462beSGnoCiYeH != 0 72971462beSGnoCiYeH } 73971462beSGnoCiYeH 74971462beSGnoCiYeH /// 让futex_q在该bucket上挂起 75971462beSGnoCiYeH /// 76971462beSGnoCiYeH /// 进入该函数前,需要关中断 77971462beSGnoCiYeH #[inline(always)] sleep_no_sched(&mut self, futex_q: Arc<FutexObj>) -> Result<(), SystemError>78971462beSGnoCiYeH pub fn sleep_no_sched(&mut self, futex_q: Arc<FutexObj>) -> Result<(), SystemError> { 79b5b571e0SLoGin assert!(!CurrentIrqArch::is_irq_enabled()); 80971462beSGnoCiYeH self.chain.push_back(futex_q); 81971462beSGnoCiYeH 82971462beSGnoCiYeH ProcessManager::mark_sleep(true)?; 83971462beSGnoCiYeH 84971462beSGnoCiYeH Ok(()) 85971462beSGnoCiYeH } 86971462beSGnoCiYeH 87971462beSGnoCiYeH /// ## 唤醒队列中的最多nr_wake个进程 88971462beSGnoCiYeH /// 89971462beSGnoCiYeH /// return: 唤醒的进程数 90971462beSGnoCiYeH #[inline(always)] wake_up( &mut self, key: FutexKey, bitset: Option<u32>, nr_wake: u32, ) -> Result<usize, SystemError>91971462beSGnoCiYeH pub fn wake_up( 92971462beSGnoCiYeH &mut self, 93971462beSGnoCiYeH key: FutexKey, 94971462beSGnoCiYeH bitset: Option<u32>, 95971462beSGnoCiYeH nr_wake: u32, 96971462beSGnoCiYeH ) -> Result<usize, SystemError> { 97971462beSGnoCiYeH let mut count = 0; 98971462beSGnoCiYeH let mut pop_count = 0; 99971462beSGnoCiYeH while let Some(futex_q) = self.chain.pop_front() { 100971462beSGnoCiYeH if futex_q.key == key { 101971462beSGnoCiYeH // TODO: 考虑优先级继承的机制 102971462beSGnoCiYeH 103971462beSGnoCiYeH if let Some(bitset) = bitset { 104971462beSGnoCiYeH if futex_q.bitset != bitset { 105971462beSGnoCiYeH self.chain.push_back(futex_q); 106971462beSGnoCiYeH continue; 107971462beSGnoCiYeH } 108971462beSGnoCiYeH } 109971462beSGnoCiYeH 110971462beSGnoCiYeH // 唤醒 111971462beSGnoCiYeH if futex_q.pcb.upgrade().is_some() { 112971462beSGnoCiYeH self.remove(futex_q.clone()); 113971462beSGnoCiYeH ProcessManager::wakeup(&futex_q.pcb.upgrade().unwrap())?; 114971462beSGnoCiYeH } 115971462beSGnoCiYeH 116971462beSGnoCiYeH // 判断唤醒数 117971462beSGnoCiYeH count += 1; 118971462beSGnoCiYeH if count >= nr_wake { 119971462beSGnoCiYeH break; 120971462beSGnoCiYeH } 121971462beSGnoCiYeH } else { 122971462beSGnoCiYeH self.chain.push_back(futex_q); 123971462beSGnoCiYeH } 124971462beSGnoCiYeH // 判断是否循环完队列了 125971462beSGnoCiYeH pop_count += 1; 126971462beSGnoCiYeH if pop_count >= self.chain.len() { 127971462beSGnoCiYeH break; 128971462beSGnoCiYeH } 129971462beSGnoCiYeH } 130971462beSGnoCiYeH Ok(count as usize) 131971462beSGnoCiYeH } 132971462beSGnoCiYeH 133971462beSGnoCiYeH /// 将FutexObj从bucket中删除 remove(&mut self, futex: Arc<FutexObj>)134971462beSGnoCiYeH pub fn remove(&mut self, futex: Arc<FutexObj>) { 1351a72a751SLoGin self.chain 1361a72a751SLoGin .extract_if(|x| Arc::ptr_eq(x, &futex)) 1371a72a751SLoGin .for_each(drop); 138971462beSGnoCiYeH } 139971462beSGnoCiYeH } 140971462beSGnoCiYeH 141971462beSGnoCiYeH #[derive(Debug)] 142971462beSGnoCiYeH pub struct FutexObj { 143971462beSGnoCiYeH pcb: Weak<ProcessControlBlock>, 144971462beSGnoCiYeH key: FutexKey, 145971462beSGnoCiYeH bitset: u32, 146971462beSGnoCiYeH // TODO: 优先级继承 147971462beSGnoCiYeH } 148971462beSGnoCiYeH 149971462beSGnoCiYeH pub enum FutexAccess { 150971462beSGnoCiYeH FutexRead, 151971462beSGnoCiYeH FutexWrite, 152971462beSGnoCiYeH } 153971462beSGnoCiYeH 154971462beSGnoCiYeH #[allow(dead_code)] 155971462beSGnoCiYeH #[derive(Hash, PartialEq, Eq, Clone, Debug)] 156971462beSGnoCiYeH /// ### 用于定位内核唯一的futex 157971462beSGnoCiYeH pub enum InnerFutexKey { 158971462beSGnoCiYeH Shared(SharedKey), 159971462beSGnoCiYeH Private(PrivateKey), 160971462beSGnoCiYeH } 161971462beSGnoCiYeH 162971462beSGnoCiYeH #[derive(Hash, PartialEq, Eq, Clone, Debug)] 163971462beSGnoCiYeH pub struct FutexKey { 164971462beSGnoCiYeH ptr: u64, 165971462beSGnoCiYeH word: u64, 166971462beSGnoCiYeH offset: u32, 167971462beSGnoCiYeH key: InnerFutexKey, 168971462beSGnoCiYeH } 169971462beSGnoCiYeH 170971462beSGnoCiYeH /// 不同进程间通过文件共享futex变量,表明该变量在文件中的位置 171971462beSGnoCiYeH #[derive(Hash, PartialEq, Eq, Clone, Debug)] 172971462beSGnoCiYeH pub struct SharedKey { 173971462beSGnoCiYeH i_seq: u64, 174971462beSGnoCiYeH page_offset: u64, 175971462beSGnoCiYeH } 176971462beSGnoCiYeH 177971462beSGnoCiYeH /// 同一进程的不同线程共享futex变量,表明该变量在进程地址空间中的位置 178971462beSGnoCiYeH #[derive(Clone, Debug)] 179971462beSGnoCiYeH pub struct PrivateKey { 180971462beSGnoCiYeH // 所在的地址空间 181971462beSGnoCiYeH address_space: Option<Weak<AddressSpace>>, 182971462beSGnoCiYeH // 表示所在页面的初始地址 183971462beSGnoCiYeH address: u64, 184971462beSGnoCiYeH } 185971462beSGnoCiYeH 186971462beSGnoCiYeH impl Hash for PrivateKey { hash<H: Hasher>(&self, state: &mut H)1871a72a751SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 188971462beSGnoCiYeH self.address.hash(state); 189971462beSGnoCiYeH } 190971462beSGnoCiYeH } 191971462beSGnoCiYeH 192971462beSGnoCiYeH impl Eq for PrivateKey {} 193971462beSGnoCiYeH 194971462beSGnoCiYeH impl PartialEq for PrivateKey { eq(&self, other: &Self) -> bool195971462beSGnoCiYeH fn eq(&self, other: &Self) -> bool { 196971462beSGnoCiYeH if self.address_space.is_none() && other.address_space.is_none() { 197971462beSGnoCiYeH return self.address == other.address; 198971462beSGnoCiYeH } else { 199971462beSGnoCiYeH return self 200971462beSGnoCiYeH .address_space 201971462beSGnoCiYeH .as_ref() 202971462beSGnoCiYeH .unwrap_or(&Weak::default()) 203b5b571e0SLoGin .ptr_eq(other.address_space.as_ref().unwrap_or(&Weak::default())) 204971462beSGnoCiYeH && self.address == other.address; 205971462beSGnoCiYeH } 206971462beSGnoCiYeH } 207971462beSGnoCiYeH } 208971462beSGnoCiYeH 209971462beSGnoCiYeH impl Futex { 210971462beSGnoCiYeH /// ### 初始化FUTEX_DATA init()211971462beSGnoCiYeH pub fn init() { 212971462beSGnoCiYeH unsafe { 213971462beSGnoCiYeH FUTEX_DATA = Some(FutexData { 214971462beSGnoCiYeH data: SpinLock::new(HashMap::new()), 215971462beSGnoCiYeH }) 216971462beSGnoCiYeH }; 217971462beSGnoCiYeH } 218971462beSGnoCiYeH 219971462beSGnoCiYeH /// ### 让当前进程在指定futex上等待直到futex_wake显式唤醒 futex_wait( uaddr: VirtAddr, flags: FutexFlag, val: u32, abs_time: Option<PosixTimeSpec>, bitset: u32, ) -> Result<usize, SystemError>220971462beSGnoCiYeH pub fn futex_wait( 221971462beSGnoCiYeH uaddr: VirtAddr, 222971462beSGnoCiYeH flags: FutexFlag, 223971462beSGnoCiYeH val: u32, 2246fc066acSJomo abs_time: Option<PosixTimeSpec>, 225971462beSGnoCiYeH bitset: u32, 226971462beSGnoCiYeH ) -> Result<usize, SystemError> { 227971462beSGnoCiYeH if bitset == 0 { 228971462beSGnoCiYeH return Err(SystemError::EINVAL); 229971462beSGnoCiYeH } 230971462beSGnoCiYeH 231971462beSGnoCiYeH // 获取全局hash表的key值 232971462beSGnoCiYeH let key = Self::get_futex_key( 233971462beSGnoCiYeH uaddr, 234971462beSGnoCiYeH flags.contains(FutexFlag::FLAGS_SHARED), 235971462beSGnoCiYeH FutexAccess::FutexRead, 236971462beSGnoCiYeH )?; 237971462beSGnoCiYeH 238971462beSGnoCiYeH let mut futex_map_guard = FutexData::futex_map(); 239971462beSGnoCiYeH let bucket = futex_map_guard.get_mut(&key); 240971462beSGnoCiYeH let bucket_mut = match bucket { 241971462beSGnoCiYeH Some(bucket) => bucket, 242971462beSGnoCiYeH None => { 243971462beSGnoCiYeH let bucket = FutexHashBucket { 244971462beSGnoCiYeH chain: LinkedList::new(), 245971462beSGnoCiYeH }; 246971462beSGnoCiYeH futex_map_guard.insert(key.clone(), bucket); 247971462beSGnoCiYeH futex_map_guard.get_mut(&key).unwrap() 248971462beSGnoCiYeH } 249971462beSGnoCiYeH }; 250971462beSGnoCiYeH 251971462beSGnoCiYeH // 使用UserBuffer读取futex 252971462beSGnoCiYeH let user_reader = 253971462beSGnoCiYeH UserBufferReader::new(uaddr.as_ptr::<u32>(), core::mem::size_of::<u32>(), true)?; 254971462beSGnoCiYeH 255971462beSGnoCiYeH // 从用户空间读取到futex的val 256971462beSGnoCiYeH let mut uval = 0; 257971462beSGnoCiYeH 258971462beSGnoCiYeH // 读取 259971462beSGnoCiYeH // 这里只尝试一种方式去读取用户空间,与linux不太一致 260971462beSGnoCiYeH // 对于linux,如果bucket被锁住时读取失败,将会将bucket解锁后重新读取 261971462beSGnoCiYeH user_reader.copy_one_from_user::<u32>(&mut uval, 0)?; 262971462beSGnoCiYeH 263971462beSGnoCiYeH // 不满足wait条件,返回错误 264971462beSGnoCiYeH if uval != val { 265971462beSGnoCiYeH return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 266971462beSGnoCiYeH } 267971462beSGnoCiYeH 268971462beSGnoCiYeH let pcb = ProcessManager::current_pcb(); 269971462beSGnoCiYeH // 创建超时计时器任务 270971462beSGnoCiYeH let mut timer = None; 271b5b571e0SLoGin if let Some(time) = abs_time { 272971462beSGnoCiYeH let wakeup_helper = WakeUpHelper::new(pcb.clone()); 273971462beSGnoCiYeH 274971462beSGnoCiYeH let sec = time.tv_sec; 275971462beSGnoCiYeH let nsec = time.tv_nsec; 276971462beSGnoCiYeH let jiffies = next_n_us_timer_jiffies((nsec / 1000 + sec * 1_000_000) as u64); 277971462beSGnoCiYeH 278971462beSGnoCiYeH let wake_up = Timer::new(wakeup_helper, jiffies); 279971462beSGnoCiYeH 280971462beSGnoCiYeH wake_up.activate(); 281971462beSGnoCiYeH timer = Some(wake_up); 282971462beSGnoCiYeH } 283971462beSGnoCiYeH 284971462beSGnoCiYeH let futex_q = Arc::new(FutexObj { 285971462beSGnoCiYeH pcb: Arc::downgrade(&pcb), 286971462beSGnoCiYeH key: key.clone(), 287971462beSGnoCiYeH bitset, 288971462beSGnoCiYeH }); 289971462beSGnoCiYeH let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 290971462beSGnoCiYeH // 满足条件则将当前进程在该bucket上挂起 291971462beSGnoCiYeH bucket_mut.sleep_no_sched(futex_q.clone()).map_err(|e| { 292*2eab6dd7S曾俊 warn!("error:{e:?}"); 293971462beSGnoCiYeH e 294971462beSGnoCiYeH })?; 295971462beSGnoCiYeH drop(futex_map_guard); 296971462beSGnoCiYeH drop(irq_guard); 297f0c87a89SGnoCiYeH schedule(SchedMode::SM_NONE); 298971462beSGnoCiYeH 299971462beSGnoCiYeH // 被唤醒后的检查 300971462beSGnoCiYeH let mut futex_map_guard = FutexData::futex_map(); 301971462beSGnoCiYeH let bucket = futex_map_guard.get_mut(&key); 302971462beSGnoCiYeH let bucket_mut = match bucket { 303971462beSGnoCiYeH // 如果该pcb不在链表里面了或者该链表已经被释放,就证明是正常的Wake操作 304971462beSGnoCiYeH Some(bucket_mut) => { 305971462beSGnoCiYeH if !bucket_mut.contains(&futex_q) { 306971462beSGnoCiYeH // 取消定时器任务 307b5b571e0SLoGin if let Some(timer) = timer { 308b5b571e0SLoGin timer.cancel(); 309971462beSGnoCiYeH } 310971462beSGnoCiYeH return Ok(0); 311971462beSGnoCiYeH } 312971462beSGnoCiYeH // 非正常唤醒,返回交给下层 313971462beSGnoCiYeH bucket_mut 314971462beSGnoCiYeH } 315971462beSGnoCiYeH None => { 316971462beSGnoCiYeH // 取消定时器任务 317b5b571e0SLoGin if let Some(timer) = timer { 318b5b571e0SLoGin timer.cancel(); 319971462beSGnoCiYeH } 320971462beSGnoCiYeH return Ok(0); 321971462beSGnoCiYeH } 322971462beSGnoCiYeH }; 323971462beSGnoCiYeH 324971462beSGnoCiYeH // 如果是超时唤醒,则返回错误 325b5b571e0SLoGin if timer.is_some() && timer.clone().unwrap().timeout() { 326971462beSGnoCiYeH bucket_mut.remove(futex_q); 327971462beSGnoCiYeH 328971462beSGnoCiYeH return Err(SystemError::ETIMEDOUT); 329971462beSGnoCiYeH } 330971462beSGnoCiYeH 331971462beSGnoCiYeH // TODO: 如果没有挂起的信号,则重新判断是否满足wait要求,重新进入wait 332971462beSGnoCiYeH 333971462beSGnoCiYeH // 经过前面的几个判断,到这里之后, 334971462beSGnoCiYeH // 当前进程被唤醒大概率是其他进程更改了uval,需要重新去判断当前进程是否满足wait 335971462beSGnoCiYeH 336971462beSGnoCiYeH // 到这里之后,前面的唤醒条件都不满足,则是被信号唤醒 337971462beSGnoCiYeH // 需要处理信号然后重启futex系统调用 338971462beSGnoCiYeH 339971462beSGnoCiYeH // 取消定时器任务 340b5b571e0SLoGin if let Some(timer) = timer { 341971462beSGnoCiYeH if !timer.timeout() { 342971462beSGnoCiYeH timer.cancel(); 343971462beSGnoCiYeH } 344971462beSGnoCiYeH } 345b5b571e0SLoGin 346971462beSGnoCiYeH Ok(0) 347971462beSGnoCiYeH } 348971462beSGnoCiYeH 349971462beSGnoCiYeH // ### 唤醒指定futex上挂起的最多nr_wake个进程 futex_wake( uaddr: VirtAddr, flags: FutexFlag, nr_wake: u32, bitset: u32, ) -> Result<usize, SystemError>350971462beSGnoCiYeH pub fn futex_wake( 351971462beSGnoCiYeH uaddr: VirtAddr, 352971462beSGnoCiYeH flags: FutexFlag, 353971462beSGnoCiYeH nr_wake: u32, 354971462beSGnoCiYeH bitset: u32, 355971462beSGnoCiYeH ) -> Result<usize, SystemError> { 356971462beSGnoCiYeH if bitset == 0 { 357971462beSGnoCiYeH return Err(SystemError::EINVAL); 358971462beSGnoCiYeH } 359971462beSGnoCiYeH 360971462beSGnoCiYeH // 获取futex_key,并且判断地址空间合法性 361971462beSGnoCiYeH let key = Self::get_futex_key( 362971462beSGnoCiYeH uaddr, 363971462beSGnoCiYeH flags.contains(FutexFlag::FLAGS_SHARED), 364971462beSGnoCiYeH FutexAccess::FutexRead, 365971462beSGnoCiYeH )?; 366971462beSGnoCiYeH let mut binding = FutexData::futex_map(); 367971462beSGnoCiYeH let bucket_mut = binding.get_mut(&key).ok_or(SystemError::EINVAL)?; 368971462beSGnoCiYeH 369971462beSGnoCiYeH // 确保后面的唤醒操作是有意义的 370971462beSGnoCiYeH if bucket_mut.chain.is_empty() { 371971462beSGnoCiYeH return Ok(0); 372971462beSGnoCiYeH } 373971462beSGnoCiYeH // 从队列中唤醒 374971462beSGnoCiYeH let count = bucket_mut.wake_up(key.clone(), Some(bitset), nr_wake)?; 375971462beSGnoCiYeH 376971462beSGnoCiYeH drop(binding); 377971462beSGnoCiYeH 378971462beSGnoCiYeH FutexData::try_remove(&key); 379971462beSGnoCiYeH 380971462beSGnoCiYeH Ok(count) 381971462beSGnoCiYeH } 382971462beSGnoCiYeH 383971462beSGnoCiYeH /// ### 唤醒制定uaddr1上的最多nr_wake个进程,然后将uaddr1最多nr_requeue个进程移动到uaddr2绑定的futex上 futex_requeue( uaddr1: VirtAddr, flags: FutexFlag, uaddr2: VirtAddr, nr_wake: i32, nr_requeue: i32, cmpval: Option<u32>, requeue_pi: bool, ) -> Result<usize, SystemError>384971462beSGnoCiYeH pub fn futex_requeue( 385971462beSGnoCiYeH uaddr1: VirtAddr, 386971462beSGnoCiYeH flags: FutexFlag, 387971462beSGnoCiYeH uaddr2: VirtAddr, 388971462beSGnoCiYeH nr_wake: i32, 389971462beSGnoCiYeH nr_requeue: i32, 390971462beSGnoCiYeH cmpval: Option<u32>, 391971462beSGnoCiYeH requeue_pi: bool, 392971462beSGnoCiYeH ) -> Result<usize, SystemError> { 393971462beSGnoCiYeH if nr_requeue < 0 || nr_wake < 0 { 394971462beSGnoCiYeH return Err(SystemError::EINVAL); 395971462beSGnoCiYeH } 396971462beSGnoCiYeH 397971462beSGnoCiYeH // 暂时不支持优先级继承 398971462beSGnoCiYeH if requeue_pi { 399971462beSGnoCiYeH return Err(SystemError::ENOSYS); 400971462beSGnoCiYeH } 401971462beSGnoCiYeH 402971462beSGnoCiYeH let key1 = Self::get_futex_key( 403971462beSGnoCiYeH uaddr1, 404971462beSGnoCiYeH flags.contains(FutexFlag::FLAGS_SHARED), 405971462beSGnoCiYeH FutexAccess::FutexRead, 406971462beSGnoCiYeH )?; 407971462beSGnoCiYeH let key2 = Self::get_futex_key(uaddr2, flags.contains(FutexFlag::FLAGS_SHARED), { 408971462beSGnoCiYeH match requeue_pi { 409971462beSGnoCiYeH true => FutexAccess::FutexWrite, 410971462beSGnoCiYeH false => FutexAccess::FutexRead, 411971462beSGnoCiYeH } 412971462beSGnoCiYeH })?; 413971462beSGnoCiYeH 414971462beSGnoCiYeH if requeue_pi && key1 == key2 { 415971462beSGnoCiYeH return Err(SystemError::EINVAL); 416971462beSGnoCiYeH } 417971462beSGnoCiYeH 418b5b571e0SLoGin if likely(cmpval.is_some()) { 419971462beSGnoCiYeH let uval_reader = 420971462beSGnoCiYeH UserBufferReader::new(uaddr1.as_ptr::<u32>(), core::mem::size_of::<u32>(), true)?; 421971462beSGnoCiYeH let curval = uval_reader.read_one_from_user::<u32>(0)?; 422971462beSGnoCiYeH 423971462beSGnoCiYeH // 判断是否满足条件 424971462beSGnoCiYeH if *curval != cmpval.unwrap() { 425971462beSGnoCiYeH return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 426971462beSGnoCiYeH } 427971462beSGnoCiYeH } 428971462beSGnoCiYeH 429971462beSGnoCiYeH let mut futex_data_guard = FutexData::futex_map(); 430971462beSGnoCiYeH if !requeue_pi { 431971462beSGnoCiYeH // 唤醒nr_wake个进程 432971462beSGnoCiYeH let bucket_1_mut = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?; 433971462beSGnoCiYeH let ret = bucket_1_mut.wake_up(key1.clone(), None, nr_wake as u32)?; 434971462beSGnoCiYeH // 将bucket1中最多nr_requeue个任务转移到bucket2 435971462beSGnoCiYeH for _ in 0..nr_requeue { 436971462beSGnoCiYeH let bucket_1_mut = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?; 437971462beSGnoCiYeH let futex_q = bucket_1_mut.chain.pop_front(); 438971462beSGnoCiYeH match futex_q { 439971462beSGnoCiYeH Some(futex_q) => { 440971462beSGnoCiYeH let bucket_2_mut = 441971462beSGnoCiYeH futex_data_guard.get_mut(&key2).ok_or(SystemError::EINVAL)?; 442971462beSGnoCiYeH bucket_2_mut.chain.push_back(futex_q); 443971462beSGnoCiYeH } 444971462beSGnoCiYeH None => { 445971462beSGnoCiYeH break; 446971462beSGnoCiYeH } 447971462beSGnoCiYeH } 448971462beSGnoCiYeH } 449971462beSGnoCiYeH 450971462beSGnoCiYeH return Ok(ret); 451971462beSGnoCiYeH } else { 452971462beSGnoCiYeH // 暂时不支持优先级继承 453971462beSGnoCiYeH todo!() 454971462beSGnoCiYeH } 455971462beSGnoCiYeH } 456971462beSGnoCiYeH 457971462beSGnoCiYeH /// ### 唤醒futex上的进程的同时进行一些操作 futex_wake_op( uaddr1: VirtAddr, flags: FutexFlag, uaddr2: VirtAddr, nr_wake: i32, nr_wake2: i32, op: i32, ) -> Result<usize, SystemError>458971462beSGnoCiYeH pub fn futex_wake_op( 459971462beSGnoCiYeH uaddr1: VirtAddr, 460971462beSGnoCiYeH flags: FutexFlag, 461971462beSGnoCiYeH uaddr2: VirtAddr, 462971462beSGnoCiYeH nr_wake: i32, 463971462beSGnoCiYeH nr_wake2: i32, 464971462beSGnoCiYeH op: i32, 465971462beSGnoCiYeH ) -> Result<usize, SystemError> { 466971462beSGnoCiYeH let key1 = Futex::get_futex_key( 467971462beSGnoCiYeH uaddr1, 468971462beSGnoCiYeH flags.contains(FutexFlag::FLAGS_SHARED), 469971462beSGnoCiYeH FutexAccess::FutexRead, 470971462beSGnoCiYeH )?; 471971462beSGnoCiYeH let key2 = Futex::get_futex_key( 472971462beSGnoCiYeH uaddr2, 473971462beSGnoCiYeH flags.contains(FutexFlag::FLAGS_SHARED), 474971462beSGnoCiYeH FutexAccess::FutexWrite, 475971462beSGnoCiYeH )?; 476971462beSGnoCiYeH 477971462beSGnoCiYeH let mut futex_data_guard = FutexData::futex_map(); 478971462beSGnoCiYeH let bucket1 = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?; 479971462beSGnoCiYeH let mut wake_count = 0; 480971462beSGnoCiYeH 481971462beSGnoCiYeH // 唤醒uaddr1中的进程 482971462beSGnoCiYeH wake_count += bucket1.wake_up(key1, None, nr_wake as u32)?; 483971462beSGnoCiYeH 484971462beSGnoCiYeH match Self::futex_atomic_op_inuser(op as u32, uaddr2) { 485971462beSGnoCiYeH Ok(ret) => { 486971462beSGnoCiYeH // 操作成功则唤醒uaddr2中的进程 487971462beSGnoCiYeH if ret { 488971462beSGnoCiYeH let bucket2 = futex_data_guard.get_mut(&key2).ok_or(SystemError::EINVAL)?; 489971462beSGnoCiYeH wake_count += bucket2.wake_up(key2, None, nr_wake2 as u32)?; 490971462beSGnoCiYeH } 491971462beSGnoCiYeH } 492971462beSGnoCiYeH Err(e) => { 493971462beSGnoCiYeH // TODO:retry? 494971462beSGnoCiYeH return Err(e); 495971462beSGnoCiYeH } 496971462beSGnoCiYeH } 497971462beSGnoCiYeH 498971462beSGnoCiYeH Ok(wake_count) 499971462beSGnoCiYeH } 500971462beSGnoCiYeH get_futex_key( uaddr: VirtAddr, fshared: bool, _access: FutexAccess, ) -> Result<FutexKey, SystemError>501971462beSGnoCiYeH fn get_futex_key( 502971462beSGnoCiYeH uaddr: VirtAddr, 503971462beSGnoCiYeH fshared: bool, 504971462beSGnoCiYeH _access: FutexAccess, 505971462beSGnoCiYeH ) -> Result<FutexKey, SystemError> { 506971462beSGnoCiYeH let mut address = uaddr.data(); 507971462beSGnoCiYeH 508971462beSGnoCiYeH // 计算相对页的偏移量 509971462beSGnoCiYeH let offset = address & (MMArch::PAGE_SIZE - 1); 510971462beSGnoCiYeH // 判断内存对齐 511b5b571e0SLoGin if uaddr.data() & (core::mem::size_of::<u32>() - 1) != 0 { 512971462beSGnoCiYeH return Err(SystemError::EINVAL); 513971462beSGnoCiYeH } 514971462beSGnoCiYeH 515971462beSGnoCiYeH // 目前address指向所在页面的起始地址 516971462beSGnoCiYeH address -= offset; 517971462beSGnoCiYeH 518971462beSGnoCiYeH // 若不是进程间共享的futex,则返回Private 519971462beSGnoCiYeH if !fshared { 520971462beSGnoCiYeH return Ok(FutexKey { 521971462beSGnoCiYeH ptr: 0, 522971462beSGnoCiYeH word: 0, 523971462beSGnoCiYeH offset: offset as u32, 524971462beSGnoCiYeH key: InnerFutexKey::Private(PrivateKey { 525971462beSGnoCiYeH address: address as u64, 526971462beSGnoCiYeH address_space: None, 527971462beSGnoCiYeH }), 528971462beSGnoCiYeH }); 529971462beSGnoCiYeH } 530971462beSGnoCiYeH 531971462beSGnoCiYeH // 获取到地址所在地址空间 532971462beSGnoCiYeH let address_space = AddressSpace::current()?; 533971462beSGnoCiYeH // TODO: 判断是否为匿名映射,是匿名映射才返回PrivateKey 534971462beSGnoCiYeH return Ok(FutexKey { 535971462beSGnoCiYeH ptr: 0, 536971462beSGnoCiYeH word: 0, 537971462beSGnoCiYeH offset: offset as u32, 538971462beSGnoCiYeH key: InnerFutexKey::Private(PrivateKey { 539971462beSGnoCiYeH address: address as u64, 540971462beSGnoCiYeH address_space: Some(Arc::downgrade(&address_space)), 541971462beSGnoCiYeH }), 542971462beSGnoCiYeH }); 543971462beSGnoCiYeH 544971462beSGnoCiYeH // 未实现共享内存机制,贡献内存部分应该通过inode构建SharedKey 545971462beSGnoCiYeH // todo!("Shared memory not implemented"); 546971462beSGnoCiYeH } 547971462beSGnoCiYeH futex_atomic_op_inuser(encoded_op: u32, uaddr: VirtAddr) -> Result<bool, SystemError>548971462beSGnoCiYeH pub fn futex_atomic_op_inuser(encoded_op: u32, uaddr: VirtAddr) -> Result<bool, SystemError> { 549971462beSGnoCiYeH let op = FutexOP::from_bits((encoded_op & 0x70000000) >> 28).ok_or(SystemError::ENOSYS)?; 550971462beSGnoCiYeH let cmp = 551971462beSGnoCiYeH FutexOpCMP::from_bits((encoded_op & 0x0f000000) >> 24).ok_or(SystemError::ENOSYS)?; 552971462beSGnoCiYeH 553971462beSGnoCiYeH let sign_extend32 = |value: u32, index: i32| { 554971462beSGnoCiYeH let shift = (31 - index) as u8; 555971462beSGnoCiYeH return (value << shift) >> shift; 556971462beSGnoCiYeH }; 557971462beSGnoCiYeH 558971462beSGnoCiYeH let mut oparg = sign_extend32((encoded_op & 0x00fff000) >> 12, 11); 559971462beSGnoCiYeH let cmparg = sign_extend32(encoded_op & 0x00000fff, 11); 560971462beSGnoCiYeH 561b5b571e0SLoGin if (encoded_op & (FutexOP::FUTEX_OP_OPARG_SHIFT.bits() << 28) != 0) && oparg > 31 { 562*2eab6dd7S曾俊 warn!( 563971462beSGnoCiYeH "futex_wake_op: pid:{} tries to shift op by {}; fix this program", 564971462beSGnoCiYeH ProcessManager::current_pcb().pid().data(), 565971462beSGnoCiYeH oparg 566971462beSGnoCiYeH ); 567971462beSGnoCiYeH 568971462beSGnoCiYeH oparg &= 31; 569971462beSGnoCiYeH } 570971462beSGnoCiYeH 571971462beSGnoCiYeH // TODO: 这个汇编似乎是有问题的,目前不好测试 572971462beSGnoCiYeH let old_val = Self::arch_futex_atomic_op_inuser(op, oparg, uaddr)?; 573971462beSGnoCiYeH 574971462beSGnoCiYeH match cmp { 575971462beSGnoCiYeH FutexOpCMP::FUTEX_OP_CMP_EQ => { 576971462beSGnoCiYeH return Ok(cmparg == old_val); 577971462beSGnoCiYeH } 578971462beSGnoCiYeH FutexOpCMP::FUTEX_OP_CMP_NE => { 579971462beSGnoCiYeH return Ok(cmparg != old_val); 580971462beSGnoCiYeH } 581971462beSGnoCiYeH FutexOpCMP::FUTEX_OP_CMP_LT => { 582971462beSGnoCiYeH return Ok(cmparg < old_val); 583971462beSGnoCiYeH } 584971462beSGnoCiYeH FutexOpCMP::FUTEX_OP_CMP_LE => { 585971462beSGnoCiYeH return Ok(cmparg <= old_val); 586971462beSGnoCiYeH } 587971462beSGnoCiYeH FutexOpCMP::FUTEX_OP_CMP_GE => { 588971462beSGnoCiYeH return Ok(cmparg >= old_val); 589971462beSGnoCiYeH } 590971462beSGnoCiYeH FutexOpCMP::FUTEX_OP_CMP_GT => { 591971462beSGnoCiYeH return Ok(cmparg > old_val); 592971462beSGnoCiYeH } 593971462beSGnoCiYeH _ => { 594971462beSGnoCiYeH return Err(SystemError::ENOSYS); 595971462beSGnoCiYeH } 596971462beSGnoCiYeH } 597971462beSGnoCiYeH } 598971462beSGnoCiYeH 599971462beSGnoCiYeH /// ### 对futex进行操作 600971462beSGnoCiYeH /// 601971462beSGnoCiYeH /// 进入该方法会关闭中断保证修改的原子性,所以进入该方法前应确保中断锁已释放 602971462beSGnoCiYeH /// 603971462beSGnoCiYeH /// ### return uaddr原来的值 604971462beSGnoCiYeH #[allow(unused_assignments)] arch_futex_atomic_op_inuser( op: FutexOP, oparg: u32, uaddr: VirtAddr, ) -> Result<u32, SystemError>605971462beSGnoCiYeH pub fn arch_futex_atomic_op_inuser( 606971462beSGnoCiYeH op: FutexOP, 607971462beSGnoCiYeH oparg: u32, 608971462beSGnoCiYeH uaddr: VirtAddr, 609971462beSGnoCiYeH ) -> Result<u32, SystemError> { 610971462beSGnoCiYeH let guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 611971462beSGnoCiYeH 612971462beSGnoCiYeH let reader = 613971462beSGnoCiYeH UserBufferReader::new(uaddr.as_ptr::<u32>(), core::mem::size_of::<u32>(), true)?; 614971462beSGnoCiYeH 615971462beSGnoCiYeH let oldval = reader.read_one_from_user::<u32>(0)?; 616971462beSGnoCiYeH 617971462beSGnoCiYeH let atomic_addr = AtomicU64::new(uaddr.data() as u64); 618971462beSGnoCiYeH // 这个指针是指向指针的指针 6191a72a751SLoGin let ptr = atomic_addr.as_ptr(); 620971462beSGnoCiYeH match op { 621971462beSGnoCiYeH FutexOP::FUTEX_OP_SET => unsafe { 622971462beSGnoCiYeH *((*ptr) as *mut u32) = oparg; 623971462beSGnoCiYeH }, 624971462beSGnoCiYeH FutexOP::FUTEX_OP_ADD => unsafe { 625971462beSGnoCiYeH *((*ptr) as *mut u32) += oparg; 626971462beSGnoCiYeH }, 627971462beSGnoCiYeH FutexOP::FUTEX_OP_OR => unsafe { 628971462beSGnoCiYeH *((*ptr) as *mut u32) |= oparg; 629971462beSGnoCiYeH }, 630971462beSGnoCiYeH FutexOP::FUTEX_OP_ANDN => unsafe { 631971462beSGnoCiYeH *((*ptr) as *mut u32) &= oparg; 632971462beSGnoCiYeH }, 633971462beSGnoCiYeH FutexOP::FUTEX_OP_XOR => unsafe { 634971462beSGnoCiYeH *((*ptr) as *mut u32) ^= oparg; 635971462beSGnoCiYeH }, 636971462beSGnoCiYeH _ => return Err(SystemError::ENOSYS), 637971462beSGnoCiYeH } 638971462beSGnoCiYeH 639971462beSGnoCiYeH drop(guard); 640971462beSGnoCiYeH 641971462beSGnoCiYeH Ok(*oldval) 642971462beSGnoCiYeH } 643971462beSGnoCiYeH } 64406560afaShmt 64506560afaShmt //用于指示在处理robust list是最多处理多少个条目 64606560afaShmt const ROBUST_LIST_LIMIT: isize = 2048; 64706560afaShmt 64806560afaShmt #[derive(Debug, Copy, Clone)] 64906560afaShmt pub struct RobustList { 65006560afaShmt next: VirtAddr, 65106560afaShmt } 65206560afaShmt 65306560afaShmt #[derive(Debug, Copy, Clone)] 65406560afaShmt pub struct RobustListHead { 65506560afaShmt list: RobustList, 65606560afaShmt futex_offset: isize, 65706560afaShmt list_op_pending: VirtAddr, 65806560afaShmt } 65906560afaShmt 66006560afaShmt impl RobustListHead { 66106560afaShmt /// # 获得futex的用户空间地址 futex_uaddr(&self, entry: VirtAddr) -> VirtAddr66206560afaShmt pub fn futex_uaddr(&self, entry: VirtAddr) -> VirtAddr { 66306560afaShmt return VirtAddr::new(entry.data() + self.futex_offset as usize); 66406560afaShmt } 66506560afaShmt 66606560afaShmt /// #获得list_op_peding的用户空间地址 pending_uaddr(&self) -> Option<VirtAddr>66706560afaShmt pub fn pending_uaddr(&self) -> Option<VirtAddr> { 66806560afaShmt if self.list_op_pending.is_null() { 66906560afaShmt return None; 67006560afaShmt } else { 67106560afaShmt return Some(self.futex_uaddr(self.list_op_pending)); 67206560afaShmt } 67306560afaShmt } 67406560afaShmt 67506560afaShmt /// # 在内核注册robust list 67606560afaShmt /// ## 参数 67706560afaShmt /// - head_uaddr:robust list head用户空间地址 67806560afaShmt /// - len:robust list head的长度 set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError>67906560afaShmt pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> { 68006560afaShmt let robust_list_head_len = mem::size_of::<&RobustListHead>(); 68106560afaShmt if unlikely(len != robust_list_head_len) { 68206560afaShmt return Err(SystemError::EINVAL); 68306560afaShmt } 68406560afaShmt 68506560afaShmt let user_buffer_reader = UserBufferReader::new( 68606560afaShmt head_uaddr.as_ptr::<RobustListHead>(), 68706560afaShmt mem::size_of::<RobustListHead>(), 68806560afaShmt true, 68906560afaShmt )?; 69006560afaShmt let robust_list_head = *user_buffer_reader.read_one_from_user::<RobustListHead>(0)?; 69106560afaShmt 69206560afaShmt // 向内核注册robust list 69306560afaShmt ProcessManager::current_pcb().set_robust_list(Some(robust_list_head)); 69406560afaShmt 69506560afaShmt return Ok(0); 69606560afaShmt } 69706560afaShmt 69806560afaShmt /// # 获取robust list head到用户空间 69906560afaShmt /// ## 参数 70006560afaShmt /// - pid:当前进程/线程的pid 70106560afaShmt /// - get_robust_list( pid: usize, head_uaddr: VirtAddr, len_ptr_uaddr: VirtAddr, ) -> Result<usize, SystemError>70206560afaShmt pub fn get_robust_list( 70306560afaShmt pid: usize, 70406560afaShmt head_uaddr: VirtAddr, 70506560afaShmt len_ptr_uaddr: VirtAddr, 70606560afaShmt ) -> Result<usize, SystemError> { 70706560afaShmt // 获取当前进程的process control block 70806560afaShmt let pcb: Arc<ProcessControlBlock> = if pid == 0 { 70906560afaShmt ProcessManager::current_pcb() 71006560afaShmt } else { 71106560afaShmt ProcessManager::find(Pid::new(pid)).ok_or(SystemError::ESRCH)? 71206560afaShmt }; 71306560afaShmt 71406560afaShmt // TODO: 检查当前进程是否能ptrace另一个进程 71506560afaShmt let ptrace = true; 71606560afaShmt if !ptrace { 71706560afaShmt return Err(SystemError::EPERM); 71806560afaShmt } 71906560afaShmt 72006560afaShmt //获取当前线程的robust list head 和 长度 72106560afaShmt let robust_list_head = (*pcb.get_robust_list()).ok_or(SystemError::EINVAL)?; 72206560afaShmt 72306560afaShmt // 将len拷贝到用户空间len_ptr 72406560afaShmt let mut user_writer = UserBufferWriter::new( 72506560afaShmt len_ptr_uaddr.as_ptr::<usize>(), 72606560afaShmt core::mem::size_of::<usize>(), 72706560afaShmt true, 72806560afaShmt )?; 72906560afaShmt user_writer.copy_one_to_user(&mem::size_of::<RobustListHead>(), 0)?; 73006560afaShmt // 将head拷贝到用户空间head 73106560afaShmt let mut user_writer = UserBufferWriter::new( 73206560afaShmt head_uaddr.as_ptr::<RobustListHead>(), 73306560afaShmt mem::size_of::<RobustListHead>(), 73406560afaShmt true, 73506560afaShmt )?; 73606560afaShmt user_writer.copy_one_to_user(&robust_list_head, 0)?; 73706560afaShmt 73806560afaShmt return Ok(0); 73906560afaShmt } 74006560afaShmt 74106560afaShmt /// # 进程/线程退出时清理工作 74206560afaShmt /// ## 参数 74306560afaShmt /// - current:当前进程/线程的pcb 74406560afaShmt /// - pid:当前进程/线程的pid exit_robust_list(pcb: Arc<ProcessControlBlock>)74506560afaShmt pub fn exit_robust_list(pcb: Arc<ProcessControlBlock>) { 74606560afaShmt //指向当前进程的robust list头部的指针 74706560afaShmt let head = match *pcb.get_robust_list() { 74806560afaShmt Some(rl) => rl, 74906560afaShmt None => { 75006560afaShmt return; 75106560afaShmt } 75206560afaShmt }; 75306560afaShmt // 遍历当前进程/线程的robust list 75406560afaShmt for futex_uaddr in head.futexes() { 75506560afaShmt let ret = Self::handle_futex_death(futex_uaddr, pcb.pid().into() as u32); 75606560afaShmt if ret.is_err() { 75706560afaShmt return; 75806560afaShmt } 75906560afaShmt } 76006560afaShmt pcb.set_robust_list(None); 76106560afaShmt } 76206560afaShmt 76306560afaShmt /// # 返回robust list的迭代器,将robust list list_op_pending 放到最后(如果存在) futexes(&self) -> FutexIterator<'_>76406560afaShmt fn futexes(&self) -> FutexIterator<'_> { 76506560afaShmt return FutexIterator::new(self); 76606560afaShmt } 76706560afaShmt 76806560afaShmt /// # 处理进程即将死亡时,进程已经持有的futex,唤醒其他等待该futex的线程 76906560afaShmt /// ## 参数 77006560afaShmt /// - futex_uaddr:futex的用户空间地址 77106560afaShmt /// - pid: 当前进程/线程的pid handle_futex_death(futex_uaddr: VirtAddr, pid: u32) -> Result<usize, SystemError>77206560afaShmt fn handle_futex_death(futex_uaddr: VirtAddr, pid: u32) -> Result<usize, SystemError> { 77306560afaShmt let futex_val = { 77406560afaShmt if futex_uaddr.is_null() { 77506560afaShmt return Err(SystemError::EINVAL); 77606560afaShmt } 77706560afaShmt let user_buffer_reader = UserBufferReader::new( 77806560afaShmt futex_uaddr.as_ptr::<u32>(), 77906560afaShmt core::mem::size_of::<u32>(), 78006560afaShmt true, 78106560afaShmt )?; 78206560afaShmt *user_buffer_reader.read_one_from_user::<u32>(0)? 78306560afaShmt }; 78406560afaShmt 78506560afaShmt let mut uval = futex_val; 78606560afaShmt loop { 78706560afaShmt // 该futex可能被其他进程占有 78806560afaShmt let owner = uval & FUTEX_TID_MASK; 78906560afaShmt if owner != pid { 79006560afaShmt break; 79106560afaShmt } 79206560afaShmt 79306560afaShmt // 判断是否有FUTEX_WAITERS和标记FUTEX_OWNER_DIED 79406560afaShmt let mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED; 79506560afaShmt 79606560afaShmt // 读取用户空间目前的futex字段,判断在此之前futex是否有被修改 79706560afaShmt let user_buffer_reader = UserBufferReader::new( 79806560afaShmt futex_uaddr.as_ptr::<u32>(), 79906560afaShmt core::mem::size_of::<u32>(), 80006560afaShmt true, 80106560afaShmt )?; 80206560afaShmt let nval = *user_buffer_reader.read_one_from_user::<u32>(0)?; 80306560afaShmt if nval != mval { 80406560afaShmt uval = nval; 80506560afaShmt let mut user_buffer_writer = UserBufferWriter::new( 80606560afaShmt futex_uaddr.as_ptr::<u32>(), 80706560afaShmt core::mem::size_of::<u32>(), 80806560afaShmt true, 80906560afaShmt )?; 81006560afaShmt user_buffer_writer.copy_one_to_user(&mval, 0)?; 81106560afaShmt continue; 81206560afaShmt } 81306560afaShmt 81406560afaShmt // 有等待者,进行唤醒操作 81506560afaShmt if nval & FUTEX_WAITERS != 0 { 81606560afaShmt let mut flags = FutexFlag::FLAGS_MATCH_NONE; 81706560afaShmt flags.insert(FutexFlag::FLAGS_SHARED); 81806560afaShmt Futex::futex_wake(futex_uaddr, flags, 1, FUTEX_BITSET_MATCH_ANY)?; 81906560afaShmt } 82006560afaShmt break; 82106560afaShmt } 82206560afaShmt 82306560afaShmt return Ok(0); 82406560afaShmt } 82506560afaShmt } 82606560afaShmt 82706560afaShmt pub struct FutexIterator<'a> { 82806560afaShmt robust_list_head: &'a RobustListHead, 82906560afaShmt entry: VirtAddr, 83006560afaShmt count: isize, 83106560afaShmt } 83206560afaShmt 83306560afaShmt impl<'a> FutexIterator<'a> { new(robust_list_head: &'a RobustListHead) -> Self83406560afaShmt pub fn new(robust_list_head: &'a RobustListHead) -> Self { 83506560afaShmt return Self { 83606560afaShmt robust_list_head, 83706560afaShmt entry: robust_list_head.list.next, 83806560afaShmt count: 0, 83906560afaShmt }; 84006560afaShmt } 84106560afaShmt is_end(&mut self) -> bool84206560afaShmt fn is_end(&mut self) -> bool { 84306560afaShmt return self.count < 0; 84406560afaShmt } 84506560afaShmt } 84606560afaShmt 84706560afaShmt impl<'a> Iterator for FutexIterator<'a> { 84806560afaShmt type Item = VirtAddr; 84906560afaShmt next(&mut self) -> Option<Self::Item>85006560afaShmt fn next(&mut self) -> Option<Self::Item> { 85106560afaShmt if self.is_end() { 85206560afaShmt return None; 85306560afaShmt } 85406560afaShmt 85506560afaShmt while self.entry.data() != &self.robust_list_head.list as *const RobustList as usize { 85606560afaShmt if self.count == ROBUST_LIST_LIMIT { 85706560afaShmt break; 85806560afaShmt } 85906560afaShmt if self.entry.is_null() { 86006560afaShmt return None; 86106560afaShmt } 86206560afaShmt 86306560afaShmt //获取futex val地址 86406560afaShmt let futex_uaddr = if self.entry.data() != self.robust_list_head.list_op_pending.data() { 86506560afaShmt Some(self.robust_list_head.futex_uaddr(self.entry)) 86606560afaShmt } else { 86706560afaShmt None 86806560afaShmt }; 86906560afaShmt 87006560afaShmt let user_buffer_reader = UserBufferReader::new( 87106560afaShmt self.entry.as_ptr::<RobustList>(), 87206560afaShmt mem::size_of::<RobustList>(), 87306560afaShmt true, 87406560afaShmt ) 87506560afaShmt .ok()?; 87606560afaShmt let next_entry = user_buffer_reader 87706560afaShmt .read_one_from_user::<RobustList>(0) 87806560afaShmt .ok()?; 87906560afaShmt 88006560afaShmt self.entry = next_entry.next; 88106560afaShmt 88206560afaShmt self.count += 1; 88306560afaShmt 88406560afaShmt if futex_uaddr.is_some() { 88506560afaShmt return futex_uaddr; 88606560afaShmt } 88706560afaShmt } 88806560afaShmt self.count -= 1; 88906560afaShmt self.robust_list_head.pending_uaddr() 89006560afaShmt } 89106560afaShmt } 892