xref: /DragonOS/kernel/src/libs/futex/futex.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
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