1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
//! 实现与futex相关的系统调用
use alloc::collections::{BTreeMap, VecDeque};
use axhal::mem::VirtAddr;
use axsync::Mutex;
use axtask::{AxTaskRef, WaitQueue};
extern crate alloc;
/// vec中的元素分别是任务指针,对应存储时的futex变量的值
pub static FUTEX_WAIT_TASK: Mutex<BTreeMap<VirtAddr, VecDeque<(AxTaskRef, u32)>>> =
Mutex::new(BTreeMap::new());
/// waiting queue which stores tasks waiting for futex variable
pub static WAIT_FOR_FUTEX: WaitQueue = WaitQueue::new();
#[derive(Default)]
/// 用于存储 robust list 的结构
pub struct FutexRobustList {
/// The location of the head of the robust list in user space
pub head: usize,
/// The length of the robust list
pub len: usize,
}
impl FutexRobustList {
/// Create a new robust list
pub fn new(head: usize, len: usize) -> Self {
Self { head, len }
}
}
/// 退出的时候清空指针
///
/// 若当前线程是主线程,代表进程退出,此时传入的id是进程id,要清除所有进程下的线程
///
/// 否则传入的id是线程id
pub fn clear_wait(id: u64, leader: bool) {
let mut futex_wait_task = FUTEX_WAIT_TASK.lock();
if leader {
// 清空所有所属进程为指定进程的线程
futex_wait_task.iter_mut().for_each(|(_, tasks)| {
// tasks.drain_filter(|task| task.get_process_id() == id);
tasks.retain(|(task, _)| task.get_process_id() != id);
});
} else {
futex_wait_task.iter_mut().for_each(|(_, tasks)| {
// tasks.drain_filter(|task| task.id().as_u64() == id);
tasks.retain(|(task, _)| task.id().as_u64() != id)
});
}
// 如果一个共享变量不会被线程所使用了,那么直接把他移除
// info!("clean pre keys: {:?}", futex_wait_task.keys());
futex_wait_task.retain(|_, tasks| !tasks.is_empty());
}