xref: /DragonOS/kernel/src/libs/futex/futex.rs (revision 4b0170bd6bb374d0e9699a0076cc23b976ad6db7)
1 use alloc::{
2     collections::LinkedList,
3     sync::{Arc, Weak},
4 };
5 use core::hash::{Hash, Hasher};
6 use core::{
7     intrinsics::{likely, unlikely},
8     mem,
9     sync::atomic::AtomicU64,
10 };
11 
12 use hashbrown::HashMap;
13 use system_error::SystemError;
14 
15 use crate::{
16     arch::{CurrentIrqArch, MMArch},
17     exception::InterruptArch,
18     libs::spinlock::{SpinLock, SpinLockGuard},
19     mm::{ucontext::AddressSpace, MemoryManagementArch, VirtAddr},
20     process::{Pid, ProcessControlBlock, ProcessManager},
21     sched::{schedule, SchedMode},
22     syscall::user_access::{UserBufferReader, UserBufferWriter},
23     time::{
24         timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
25         PosixTimeSpec,
26     },
27 };
28 
29 use super::constant::*;
30 
31 static mut FUTEX_DATA: Option<FutexData> = None;
32 
33 pub struct FutexData {
34     data: SpinLock<HashMap<FutexKey, FutexHashBucket>>,
35 }
36 
37 impl FutexData {
38     pub fn futex_map() -> SpinLockGuard<'static, HashMap<FutexKey, FutexHashBucket>> {
39         unsafe { FUTEX_DATA.as_ref().unwrap().data.lock() }
40     }
41 
42     pub fn try_remove(key: &FutexKey) -> Option<FutexHashBucket> {
43         unsafe {
44             let mut guard = FUTEX_DATA.as_ref().unwrap().data.lock();
45             if let Some(futex) = guard.get(key) {
46                 if futex.chain.is_empty() {
47                     return guard.remove(key);
48                 }
49             }
50         }
51         None
52     }
53 }
54 
55 pub struct Futex;
56 
57 // 对于同一个futex的进程或线程将会在这个bucket等待
58 pub struct FutexHashBucket {
59     // 该futex维护的等待队列
60     chain: LinkedList<Arc<FutexObj>>,
61 }
62 
63 impl FutexHashBucket {
64     /// ## 判断是否在bucket里
65     pub fn contains(&self, futex_q: &FutexObj) -> bool {
66         self.chain
67             .iter()
68             .filter(|x| futex_q.pcb.ptr_eq(&x.pcb) && x.key == futex_q.key)
69             .count()
70             != 0
71     }
72 
73     /// 让futex_q在该bucket上挂起
74     ///
75     /// 进入该函数前,需要关中断
76     #[inline(always)]
77     pub fn sleep_no_sched(&mut self, futex_q: Arc<FutexObj>) -> Result<(), SystemError> {
78         assert!(!CurrentIrqArch::is_irq_enabled());
79         self.chain.push_back(futex_q);
80 
81         ProcessManager::mark_sleep(true)?;
82 
83         Ok(())
84     }
85 
86     /// ## 唤醒队列中的最多nr_wake个进程
87     ///
88     /// return: 唤醒的进程数
89     #[inline(always)]
90     pub fn wake_up(
91         &mut self,
92         key: FutexKey,
93         bitset: Option<u32>,
94         nr_wake: u32,
95     ) -> Result<usize, SystemError> {
96         let mut count = 0;
97         let mut pop_count = 0;
98         while let Some(futex_q) = self.chain.pop_front() {
99             if futex_q.key == key {
100                 // TODO: 考虑优先级继承的机制
101 
102                 if let Some(bitset) = bitset {
103                     if futex_q.bitset != bitset {
104                         self.chain.push_back(futex_q);
105                         continue;
106                     }
107                 }
108 
109                 // 唤醒
110                 if futex_q.pcb.upgrade().is_some() {
111                     self.remove(futex_q.clone());
112                     ProcessManager::wakeup(&futex_q.pcb.upgrade().unwrap())?;
113                 }
114 
115                 // 判断唤醒数
116                 count += 1;
117                 if count >= nr_wake {
118                     break;
119                 }
120             } else {
121                 self.chain.push_back(futex_q);
122             }
123             // 判断是否循环完队列了
124             pop_count += 1;
125             if pop_count >= self.chain.len() {
126                 break;
127             }
128         }
129         Ok(count as usize)
130     }
131 
132     /// 将FutexObj从bucket中删除
133     pub fn remove(&mut self, futex: Arc<FutexObj>) {
134         self.chain
135             .extract_if(|x| Arc::ptr_eq(x, &futex))
136             .for_each(drop);
137     }
138 }
139 
140 #[derive(Debug)]
141 pub struct FutexObj {
142     pcb: Weak<ProcessControlBlock>,
143     key: FutexKey,
144     bitset: u32,
145     // TODO: 优先级继承
146 }
147 
148 pub enum FutexAccess {
149     FutexRead,
150     FutexWrite,
151 }
152 
153 #[allow(dead_code)]
154 #[derive(Hash, PartialEq, Eq, Clone, Debug)]
155 /// ### 用于定位内核唯一的futex
156 pub enum InnerFutexKey {
157     Shared(SharedKey),
158     Private(PrivateKey),
159 }
160 
161 #[derive(Hash, PartialEq, Eq, Clone, Debug)]
162 pub struct FutexKey {
163     ptr: u64,
164     word: u64,
165     offset: u32,
166     key: InnerFutexKey,
167 }
168 
169 /// 不同进程间通过文件共享futex变量,表明该变量在文件中的位置
170 #[derive(Hash, PartialEq, Eq, Clone, Debug)]
171 pub struct SharedKey {
172     i_seq: u64,
173     page_offset: u64,
174 }
175 
176 /// 同一进程的不同线程共享futex变量,表明该变量在进程地址空间中的位置
177 #[derive(Clone, Debug)]
178 pub struct PrivateKey {
179     // 所在的地址空间
180     address_space: Option<Weak<AddressSpace>>,
181     // 表示所在页面的初始地址
182     address: u64,
183 }
184 
185 impl Hash for PrivateKey {
186     fn hash<H: Hasher>(&self, state: &mut H) {
187         self.address.hash(state);
188     }
189 }
190 
191 impl Eq for PrivateKey {}
192 
193 impl PartialEq for PrivateKey {
194     fn eq(&self, other: &Self) -> bool {
195         if self.address_space.is_none() && other.address_space.is_none() {
196             return self.address == other.address;
197         } else {
198             return self
199                 .address_space
200                 .as_ref()
201                 .unwrap_or(&Weak::default())
202                 .ptr_eq(other.address_space.as_ref().unwrap_or(&Weak::default()))
203                 && self.address == other.address;
204         }
205     }
206 }
207 
208 impl Futex {
209     /// ### 初始化FUTEX_DATA
210     pub fn init() {
211         unsafe {
212             FUTEX_DATA = Some(FutexData {
213                 data: SpinLock::new(HashMap::new()),
214             })
215         };
216     }
217 
218     /// ### 让当前进程在指定futex上等待直到futex_wake显式唤醒
219     pub fn futex_wait(
220         uaddr: VirtAddr,
221         flags: FutexFlag,
222         val: u32,
223         abs_time: Option<PosixTimeSpec>,
224         bitset: u32,
225     ) -> Result<usize, SystemError> {
226         if bitset == 0 {
227             return Err(SystemError::EINVAL);
228         }
229 
230         // 获取全局hash表的key值
231         let key = Self::get_futex_key(
232             uaddr,
233             flags.contains(FutexFlag::FLAGS_SHARED),
234             FutexAccess::FutexRead,
235         )?;
236 
237         let mut futex_map_guard = FutexData::futex_map();
238         let bucket = futex_map_guard.get_mut(&key);
239         let bucket_mut = match bucket {
240             Some(bucket) => bucket,
241             None => {
242                 let bucket = FutexHashBucket {
243                     chain: LinkedList::new(),
244                 };
245                 futex_map_guard.insert(key.clone(), bucket);
246                 futex_map_guard.get_mut(&key).unwrap()
247             }
248         };
249 
250         // 使用UserBuffer读取futex
251         let user_reader =
252             UserBufferReader::new(uaddr.as_ptr::<u32>(), core::mem::size_of::<u32>(), true)?;
253 
254         // 从用户空间读取到futex的val
255         let mut uval = 0;
256 
257         // 读取
258         // 这里只尝试一种方式去读取用户空间,与linux不太一致
259         // 对于linux,如果bucket被锁住时读取失败,将会将bucket解锁后重新读取
260         user_reader.copy_one_from_user::<u32>(&mut uval, 0)?;
261 
262         // 不满足wait条件,返回错误
263         if uval != val {
264             return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
265         }
266 
267         let pcb = ProcessManager::current_pcb();
268         // 创建超时计时器任务
269         let mut timer = None;
270         if let Some(time) = abs_time {
271             let wakeup_helper = WakeUpHelper::new(pcb.clone());
272 
273             let sec = time.tv_sec;
274             let nsec = time.tv_nsec;
275             let jiffies = next_n_us_timer_jiffies((nsec / 1000 + sec * 1_000_000) as u64);
276 
277             let wake_up = Timer::new(wakeup_helper, jiffies);
278 
279             wake_up.activate();
280             timer = Some(wake_up);
281         }
282 
283         let futex_q = Arc::new(FutexObj {
284             pcb: Arc::downgrade(&pcb),
285             key: key.clone(),
286             bitset,
287         });
288         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
289         // 满足条件则将当前进程在该bucket上挂起
290         bucket_mut.sleep_no_sched(futex_q.clone()).map_err(|e| {
291             kwarn!("error:{e:?}");
292             e
293         })?;
294         drop(futex_map_guard);
295         drop(irq_guard);
296         schedule(SchedMode::SM_NONE);
297 
298         // 被唤醒后的检查
299         let mut futex_map_guard = FutexData::futex_map();
300         let bucket = futex_map_guard.get_mut(&key);
301         let bucket_mut = match bucket {
302             // 如果该pcb不在链表里面了或者该链表已经被释放,就证明是正常的Wake操作
303             Some(bucket_mut) => {
304                 if !bucket_mut.contains(&futex_q) {
305                     // 取消定时器任务
306                     if let Some(timer) = timer {
307                         timer.cancel();
308                     }
309                     return Ok(0);
310                 }
311                 // 非正常唤醒,返回交给下层
312                 bucket_mut
313             }
314             None => {
315                 // 取消定时器任务
316                 if let Some(timer) = timer {
317                     timer.cancel();
318                 }
319                 return Ok(0);
320             }
321         };
322 
323         // 如果是超时唤醒,则返回错误
324         if timer.is_some() && timer.clone().unwrap().timeout() {
325             bucket_mut.remove(futex_q);
326 
327             return Err(SystemError::ETIMEDOUT);
328         }
329 
330         // TODO: 如果没有挂起的信号,则重新判断是否满足wait要求,重新进入wait
331 
332         // 经过前面的几个判断,到这里之后,
333         // 当前进程被唤醒大概率是其他进程更改了uval,需要重新去判断当前进程是否满足wait
334 
335         // 到这里之后,前面的唤醒条件都不满足,则是被信号唤醒
336         // 需要处理信号然后重启futex系统调用
337 
338         // 取消定时器任务
339         if let Some(timer) = timer {
340             if !timer.timeout() {
341                 timer.cancel();
342             }
343         }
344 
345         Ok(0)
346     }
347 
348     // ### 唤醒指定futex上挂起的最多nr_wake个进程
349     pub fn futex_wake(
350         uaddr: VirtAddr,
351         flags: FutexFlag,
352         nr_wake: u32,
353         bitset: u32,
354     ) -> Result<usize, SystemError> {
355         if bitset == 0 {
356             return Err(SystemError::EINVAL);
357         }
358 
359         // 获取futex_key,并且判断地址空间合法性
360         let key = Self::get_futex_key(
361             uaddr,
362             flags.contains(FutexFlag::FLAGS_SHARED),
363             FutexAccess::FutexRead,
364         )?;
365         let mut binding = FutexData::futex_map();
366         let bucket_mut = binding.get_mut(&key).ok_or(SystemError::EINVAL)?;
367 
368         // 确保后面的唤醒操作是有意义的
369         if bucket_mut.chain.is_empty() {
370             return Ok(0);
371         }
372         // 从队列中唤醒
373         let count = bucket_mut.wake_up(key.clone(), Some(bitset), nr_wake)?;
374 
375         drop(binding);
376 
377         FutexData::try_remove(&key);
378 
379         Ok(count)
380     }
381 
382     /// ### 唤醒制定uaddr1上的最多nr_wake个进程,然后将uaddr1最多nr_requeue个进程移动到uaddr2绑定的futex上
383     pub fn futex_requeue(
384         uaddr1: VirtAddr,
385         flags: FutexFlag,
386         uaddr2: VirtAddr,
387         nr_wake: i32,
388         nr_requeue: i32,
389         cmpval: Option<u32>,
390         requeue_pi: bool,
391     ) -> Result<usize, SystemError> {
392         if nr_requeue < 0 || nr_wake < 0 {
393             return Err(SystemError::EINVAL);
394         }
395 
396         // 暂时不支持优先级继承
397         if requeue_pi {
398             return Err(SystemError::ENOSYS);
399         }
400 
401         let key1 = Self::get_futex_key(
402             uaddr1,
403             flags.contains(FutexFlag::FLAGS_SHARED),
404             FutexAccess::FutexRead,
405         )?;
406         let key2 = Self::get_futex_key(uaddr2, flags.contains(FutexFlag::FLAGS_SHARED), {
407             match requeue_pi {
408                 true => FutexAccess::FutexWrite,
409                 false => FutexAccess::FutexRead,
410             }
411         })?;
412 
413         if requeue_pi && key1 == key2 {
414             return Err(SystemError::EINVAL);
415         }
416 
417         if likely(cmpval.is_some()) {
418             let uval_reader =
419                 UserBufferReader::new(uaddr1.as_ptr::<u32>(), core::mem::size_of::<u32>(), true)?;
420             let curval = uval_reader.read_one_from_user::<u32>(0)?;
421 
422             // 判断是否满足条件
423             if *curval != cmpval.unwrap() {
424                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
425             }
426         }
427 
428         let mut futex_data_guard = FutexData::futex_map();
429         if !requeue_pi {
430             // 唤醒nr_wake个进程
431             let bucket_1_mut = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?;
432             let ret = bucket_1_mut.wake_up(key1.clone(), None, nr_wake as u32)?;
433             // 将bucket1中最多nr_requeue个任务转移到bucket2
434             for _ in 0..nr_requeue {
435                 let bucket_1_mut = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?;
436                 let futex_q = bucket_1_mut.chain.pop_front();
437                 match futex_q {
438                     Some(futex_q) => {
439                         let bucket_2_mut =
440                             futex_data_guard.get_mut(&key2).ok_or(SystemError::EINVAL)?;
441                         bucket_2_mut.chain.push_back(futex_q);
442                     }
443                     None => {
444                         break;
445                     }
446                 }
447             }
448 
449             return Ok(ret);
450         } else {
451             // 暂时不支持优先级继承
452             todo!()
453         }
454     }
455 
456     /// ### 唤醒futex上的进程的同时进行一些操作
457     pub fn futex_wake_op(
458         uaddr1: VirtAddr,
459         flags: FutexFlag,
460         uaddr2: VirtAddr,
461         nr_wake: i32,
462         nr_wake2: i32,
463         op: i32,
464     ) -> Result<usize, SystemError> {
465         let key1 = Futex::get_futex_key(
466             uaddr1,
467             flags.contains(FutexFlag::FLAGS_SHARED),
468             FutexAccess::FutexRead,
469         )?;
470         let key2 = Futex::get_futex_key(
471             uaddr2,
472             flags.contains(FutexFlag::FLAGS_SHARED),
473             FutexAccess::FutexWrite,
474         )?;
475 
476         let mut futex_data_guard = FutexData::futex_map();
477         let bucket1 = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?;
478         let mut wake_count = 0;
479 
480         // 唤醒uaddr1中的进程
481         wake_count += bucket1.wake_up(key1, None, nr_wake as u32)?;
482 
483         match Self::futex_atomic_op_inuser(op as u32, uaddr2) {
484             Ok(ret) => {
485                 // 操作成功则唤醒uaddr2中的进程
486                 if ret {
487                     let bucket2 = futex_data_guard.get_mut(&key2).ok_or(SystemError::EINVAL)?;
488                     wake_count += bucket2.wake_up(key2, None, nr_wake2 as u32)?;
489                 }
490             }
491             Err(e) => {
492                 // TODO:retry?
493                 return Err(e);
494             }
495         }
496 
497         Ok(wake_count)
498     }
499 
500     fn get_futex_key(
501         uaddr: VirtAddr,
502         fshared: bool,
503         _access: FutexAccess,
504     ) -> Result<FutexKey, SystemError> {
505         let mut address = uaddr.data();
506 
507         // 计算相对页的偏移量
508         let offset = address & (MMArch::PAGE_SIZE - 1);
509         // 判断内存对齐
510         if uaddr.data() & (core::mem::size_of::<u32>() - 1) != 0 {
511             return Err(SystemError::EINVAL);
512         }
513 
514         // 目前address指向所在页面的起始地址
515         address -= offset;
516 
517         // 若不是进程间共享的futex,则返回Private
518         if !fshared {
519             return Ok(FutexKey {
520                 ptr: 0,
521                 word: 0,
522                 offset: offset as u32,
523                 key: InnerFutexKey::Private(PrivateKey {
524                     address: address as u64,
525                     address_space: None,
526                 }),
527             });
528         }
529 
530         // 获取到地址所在地址空间
531         let address_space = AddressSpace::current()?;
532         // TODO: 判断是否为匿名映射,是匿名映射才返回PrivateKey
533         return Ok(FutexKey {
534             ptr: 0,
535             word: 0,
536             offset: offset as u32,
537             key: InnerFutexKey::Private(PrivateKey {
538                 address: address as u64,
539                 address_space: Some(Arc::downgrade(&address_space)),
540             }),
541         });
542 
543         // 未实现共享内存机制,贡献内存部分应该通过inode构建SharedKey
544         // todo!("Shared memory not implemented");
545     }
546 
547     pub fn futex_atomic_op_inuser(encoded_op: u32, uaddr: VirtAddr) -> Result<bool, SystemError> {
548         let op = FutexOP::from_bits((encoded_op & 0x70000000) >> 28).ok_or(SystemError::ENOSYS)?;
549         let cmp =
550             FutexOpCMP::from_bits((encoded_op & 0x0f000000) >> 24).ok_or(SystemError::ENOSYS)?;
551 
552         let sign_extend32 = |value: u32, index: i32| {
553             let shift = (31 - index) as u8;
554             return (value << shift) >> shift;
555         };
556 
557         let mut oparg = sign_extend32((encoded_op & 0x00fff000) >> 12, 11);
558         let cmparg = sign_extend32(encoded_op & 0x00000fff, 11);
559 
560         if (encoded_op & (FutexOP::FUTEX_OP_OPARG_SHIFT.bits() << 28) != 0) && oparg > 31 {
561             kwarn!(
562                 "futex_wake_op: pid:{} tries to shift op by {}; fix this program",
563                 ProcessManager::current_pcb().pid().data(),
564                 oparg
565             );
566 
567             oparg &= 31;
568         }
569 
570         // TODO: 这个汇编似乎是有问题的,目前不好测试
571         let old_val = Self::arch_futex_atomic_op_inuser(op, oparg, uaddr)?;
572 
573         match cmp {
574             FutexOpCMP::FUTEX_OP_CMP_EQ => {
575                 return Ok(cmparg == old_val);
576             }
577             FutexOpCMP::FUTEX_OP_CMP_NE => {
578                 return Ok(cmparg != old_val);
579             }
580             FutexOpCMP::FUTEX_OP_CMP_LT => {
581                 return Ok(cmparg < old_val);
582             }
583             FutexOpCMP::FUTEX_OP_CMP_LE => {
584                 return Ok(cmparg <= old_val);
585             }
586             FutexOpCMP::FUTEX_OP_CMP_GE => {
587                 return Ok(cmparg >= old_val);
588             }
589             FutexOpCMP::FUTEX_OP_CMP_GT => {
590                 return Ok(cmparg > old_val);
591             }
592             _ => {
593                 return Err(SystemError::ENOSYS);
594             }
595         }
596     }
597 
598     /// ### 对futex进行操作
599     ///
600     /// 进入该方法会关闭中断保证修改的原子性,所以进入该方法前应确保中断锁已释放
601     ///
602     /// ### return uaddr原来的值
603     #[allow(unused_assignments)]
604     pub fn arch_futex_atomic_op_inuser(
605         op: FutexOP,
606         oparg: u32,
607         uaddr: VirtAddr,
608     ) -> Result<u32, SystemError> {
609         let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
610 
611         let reader =
612             UserBufferReader::new(uaddr.as_ptr::<u32>(), core::mem::size_of::<u32>(), true)?;
613 
614         let oldval = reader.read_one_from_user::<u32>(0)?;
615 
616         let atomic_addr = AtomicU64::new(uaddr.data() as u64);
617         // 这个指针是指向指针的指针
618         let ptr = atomic_addr.as_ptr();
619         match op {
620             FutexOP::FUTEX_OP_SET => unsafe {
621                 *((*ptr) as *mut u32) = oparg;
622             },
623             FutexOP::FUTEX_OP_ADD => unsafe {
624                 *((*ptr) as *mut u32) += oparg;
625             },
626             FutexOP::FUTEX_OP_OR => unsafe {
627                 *((*ptr) as *mut u32) |= oparg;
628             },
629             FutexOP::FUTEX_OP_ANDN => unsafe {
630                 *((*ptr) as *mut u32) &= oparg;
631             },
632             FutexOP::FUTEX_OP_XOR => unsafe {
633                 *((*ptr) as *mut u32) ^= oparg;
634             },
635             _ => return Err(SystemError::ENOSYS),
636         }
637 
638         drop(guard);
639 
640         Ok(*oldval)
641     }
642 }
643 
644 //用于指示在处理robust list是最多处理多少个条目
645 const ROBUST_LIST_LIMIT: isize = 2048;
646 
647 #[derive(Debug, Copy, Clone)]
648 pub struct RobustList {
649     next: VirtAddr,
650 }
651 
652 #[derive(Debug, Copy, Clone)]
653 pub struct RobustListHead {
654     list: RobustList,
655     futex_offset: isize,
656     list_op_pending: VirtAddr,
657 }
658 
659 impl RobustListHead {
660     /// # 获得futex的用户空间地址
661     pub fn futex_uaddr(&self, entry: VirtAddr) -> VirtAddr {
662         return VirtAddr::new(entry.data() + self.futex_offset as usize);
663     }
664 
665     /// #获得list_op_peding的用户空间地址
666     pub fn pending_uaddr(&self) -> Option<VirtAddr> {
667         if self.list_op_pending.is_null() {
668             return None;
669         } else {
670             return Some(self.futex_uaddr(self.list_op_pending));
671         }
672     }
673 
674     /// # 在内核注册robust list
675     /// ## 参数
676     /// - head_uaddr:robust list head用户空间地址
677     /// - len:robust list head的长度
678     pub fn set_robust_list(head_uaddr: VirtAddr, len: usize) -> Result<usize, SystemError> {
679         let robust_list_head_len = mem::size_of::<&RobustListHead>();
680         if unlikely(len != robust_list_head_len) {
681             return Err(SystemError::EINVAL);
682         }
683 
684         let user_buffer_reader = UserBufferReader::new(
685             head_uaddr.as_ptr::<RobustListHead>(),
686             mem::size_of::<RobustListHead>(),
687             true,
688         )?;
689         let robust_list_head = *user_buffer_reader.read_one_from_user::<RobustListHead>(0)?;
690 
691         // 向内核注册robust list
692         ProcessManager::current_pcb().set_robust_list(Some(robust_list_head));
693 
694         return Ok(0);
695     }
696 
697     /// # 获取robust list head到用户空间
698     /// ## 参数
699     /// - pid:当前进程/线程的pid
700     /// -
701     pub fn get_robust_list(
702         pid: usize,
703         head_uaddr: VirtAddr,
704         len_ptr_uaddr: VirtAddr,
705     ) -> Result<usize, SystemError> {
706         // 获取当前进程的process control block
707         let pcb: Arc<ProcessControlBlock> = if pid == 0 {
708             ProcessManager::current_pcb()
709         } else {
710             ProcessManager::find(Pid::new(pid)).ok_or(SystemError::ESRCH)?
711         };
712 
713         // TODO: 检查当前进程是否能ptrace另一个进程
714         let ptrace = true;
715         if !ptrace {
716             return Err(SystemError::EPERM);
717         }
718 
719         //获取当前线程的robust list head 和 长度
720         let robust_list_head = (*pcb.get_robust_list()).ok_or(SystemError::EINVAL)?;
721 
722         // 将len拷贝到用户空间len_ptr
723         let mut user_writer = UserBufferWriter::new(
724             len_ptr_uaddr.as_ptr::<usize>(),
725             core::mem::size_of::<usize>(),
726             true,
727         )?;
728         user_writer.copy_one_to_user(&mem::size_of::<RobustListHead>(), 0)?;
729         // 将head拷贝到用户空间head
730         let mut user_writer = UserBufferWriter::new(
731             head_uaddr.as_ptr::<RobustListHead>(),
732             mem::size_of::<RobustListHead>(),
733             true,
734         )?;
735         user_writer.copy_one_to_user(&robust_list_head, 0)?;
736 
737         return Ok(0);
738     }
739 
740     /// # 进程/线程退出时清理工作
741     /// ## 参数
742     /// - current:当前进程/线程的pcb
743     /// - pid:当前进程/线程的pid
744     pub fn exit_robust_list(pcb: Arc<ProcessControlBlock>) {
745         //指向当前进程的robust list头部的指针
746         let head = match *pcb.get_robust_list() {
747             Some(rl) => rl,
748             None => {
749                 return;
750             }
751         };
752         // 遍历当前进程/线程的robust list
753         for futex_uaddr in head.futexes() {
754             let ret = Self::handle_futex_death(futex_uaddr, pcb.pid().into() as u32);
755             if ret.is_err() {
756                 return;
757             }
758         }
759         pcb.set_robust_list(None);
760     }
761 
762     /// # 返回robust list的迭代器,将robust list list_op_pending 放到最后(如果存在)
763     fn futexes(&self) -> FutexIterator<'_> {
764         return FutexIterator::new(self);
765     }
766 
767     /// # 处理进程即将死亡时,进程已经持有的futex,唤醒其他等待该futex的线程
768     /// ## 参数
769     /// - futex_uaddr:futex的用户空间地址
770     /// - pid: 当前进程/线程的pid
771     fn handle_futex_death(futex_uaddr: VirtAddr, pid: u32) -> Result<usize, SystemError> {
772         let futex_val = {
773             if futex_uaddr.is_null() {
774                 return Err(SystemError::EINVAL);
775             }
776             let user_buffer_reader = UserBufferReader::new(
777                 futex_uaddr.as_ptr::<u32>(),
778                 core::mem::size_of::<u32>(),
779                 true,
780             )?;
781             *user_buffer_reader.read_one_from_user::<u32>(0)?
782         };
783 
784         let mut uval = futex_val;
785         loop {
786             // 该futex可能被其他进程占有
787             let owner = uval & FUTEX_TID_MASK;
788             if owner != pid {
789                 break;
790             }
791 
792             // 判断是否有FUTEX_WAITERS和标记FUTEX_OWNER_DIED
793             let mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
794 
795             // 读取用户空间目前的futex字段,判断在此之前futex是否有被修改
796             let user_buffer_reader = UserBufferReader::new(
797                 futex_uaddr.as_ptr::<u32>(),
798                 core::mem::size_of::<u32>(),
799                 true,
800             )?;
801             let nval = *user_buffer_reader.read_one_from_user::<u32>(0)?;
802             if nval != mval {
803                 uval = nval;
804                 let mut user_buffer_writer = UserBufferWriter::new(
805                     futex_uaddr.as_ptr::<u32>(),
806                     core::mem::size_of::<u32>(),
807                     true,
808                 )?;
809                 user_buffer_writer.copy_one_to_user(&mval, 0)?;
810                 continue;
811             }
812 
813             // 有等待者,进行唤醒操作
814             if nval & FUTEX_WAITERS != 0 {
815                 let mut flags = FutexFlag::FLAGS_MATCH_NONE;
816                 flags.insert(FutexFlag::FLAGS_SHARED);
817                 Futex::futex_wake(futex_uaddr, flags, 1, FUTEX_BITSET_MATCH_ANY)?;
818             }
819             break;
820         }
821 
822         return Ok(0);
823     }
824 }
825 
826 pub struct FutexIterator<'a> {
827     robust_list_head: &'a RobustListHead,
828     entry: VirtAddr,
829     count: isize,
830 }
831 
832 impl<'a> FutexIterator<'a> {
833     pub fn new(robust_list_head: &'a RobustListHead) -> Self {
834         return Self {
835             robust_list_head,
836             entry: robust_list_head.list.next,
837             count: 0,
838         };
839     }
840 
841     fn is_end(&mut self) -> bool {
842         return self.count < 0;
843     }
844 }
845 
846 impl<'a> Iterator for FutexIterator<'a> {
847     type Item = VirtAddr;
848 
849     fn next(&mut self) -> Option<Self::Item> {
850         if self.is_end() {
851             return None;
852         }
853 
854         while self.entry.data() != &self.robust_list_head.list as *const RobustList as usize {
855             if self.count == ROBUST_LIST_LIMIT {
856                 break;
857             }
858             if self.entry.is_null() {
859                 return None;
860             }
861 
862             //获取futex val地址
863             let futex_uaddr = if self.entry.data() != self.robust_list_head.list_op_pending.data() {
864                 Some(self.robust_list_head.futex_uaddr(self.entry))
865             } else {
866                 None
867             };
868 
869             let user_buffer_reader = UserBufferReader::new(
870                 self.entry.as_ptr::<RobustList>(),
871                 mem::size_of::<RobustList>(),
872                 true,
873             )
874             .ok()?;
875             let next_entry = user_buffer_reader
876                 .read_one_from_user::<RobustList>(0)
877                 .ok()?;
878 
879             self.entry = next_entry.next;
880 
881             self.count += 1;
882 
883             if futex_uaddr.is_some() {
884                 return futex_uaddr;
885             }
886         }
887         self.count -= 1;
888         self.robust_list_head.pending_uaddr()
889     }
890 }
891