os/kernel/syscall/
task.rs

1//! 任务相关的系统调用实现
2
3use core::{
4    ffi::{c_char, c_int, c_ulong, c_void},
5    sync::atomic::Ordering,
6};
7
8use alloc::{string::ToString, sync::Arc, vec::Vec};
9
10use crate::{
11    arch::{
12        timer::{clock_freq, get_time},
13        trap::{SumGuard, restore},
14    },
15    ipc::{SignalHandlerTable, SignalPending, signal_pending},
16    kernel::{
17        FUTEX_MANAGER, SCHEDULER, Scheduler, SharedTask, TASK_MANAGER, TIMER, TIMER_QUEUE,
18        TaskManagerTrait, TaskState, TaskStruct, TimerEntry, current_cpu, current_task,
19        exit_process, schedule, sleep_task_with_block, sleep_task_with_guard_and_block,
20        syscall::util::{get_args_safe, get_path_safe},
21        time::{REALTIME, realtime_now},
22        yield_task,
23    },
24    mm::{
25        address::{UsizeConvert, Vaddr},
26        frame_allocator::{alloc_contig_frames, alloc_frame},
27        memory_space::MemorySpace,
28    },
29    sync::SpinLock,
30    uapi::{
31        errno::{
32            EAGAIN, EFAULT, EINTR, EINVAL, EIO, EISDIR, ENOENT, ENOEXEC, ENOSYS, EPERM, ESRCH,
33            ETIMEDOUT,
34        },
35        futex::{FUTEX_CLOCK_REALTIME, FUTEX_PRIVATE, FUTEX_WAIT, FUTEX_WAKE, RobustListHead},
36        resource::{RLIM_NLIMITS, Rlimit, Rusage},
37        sched::CloneFlags,
38        signal::{NUM_SIGALRM, NUM_SIGPROF, NUM_SIGVTALRM},
39        time::{
40            Itimerval, TimeSpec,
41            clock_flags::TIMER_ABSTIME,
42            clock_id::{
43                CLOCK_BOOTTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, CLOCK_REALTIME,
44                CLOCK_TAI,
45            },
46            itimer_id::{ITIMER_PROF, ITIMER_REAL, ITIMER_VIRTUAL},
47        },
48        types::{SizeT, StackT},
49        wait::{WaitFlags, WaitStatus},
50    },
51    util::user_buffer::{read_from_user, write_to_user},
52    vfs::FsError,
53};
54
55/// 线程退出系统调用
56/// # 说明
57/// 终止调用该系统调用的执行流(即线程)
58/// 对于非主线程, 该线程立即终止。内核回收该线程的栈和其他线程特定的资源。
59/// 进程中的其他线程继续正常执行。
60/// 对于主线程, 该线程终止整个进程,
61/// 除非进程中有其他线程调用 execve() 或等待其子线程终止(TODO: 该行为待验证)
62/// # 参数
63/// - `code`: 退出代码
64pub fn exit(code: c_int) -> c_int {
65    // TODO: 处理 tid_addr 和 robust_list
66    // TODO: clear_child_tid 的处理
67    let task = current_task();
68    if task.lock().is_process() {
69        exit_process(task, code & 0xFF);
70    } else {
71        TASK_MANAGER.lock().exit_task(task, code & 0xFF);
72    }
73    schedule();
74    unreachable!("exit: exit_task should not return.");
75}
76
77/// 进程 (线程组) 退出系统调用
78/// # 说明
79/// exit_group() 函数将"立即"终止调用进程。该进程拥有的所有打开文件描述符均被关闭。
80/// 该进程的所有子进程将由 init(1) 进程(TODO: 或通过 prctl(2) 的
81/// PR_SET_CHILD_SUBREAPER 操作定义的最近"子进程回收器"进程)继承。
82/// 进程父进程将收到 SIGCHLD 信号。
83/// 返回值 code & 0xFF作为进程退出状态传递给父进程,
84/// 父进程可通过wait(2)系列调用之一获取该状态。
85/// # 参数
86/// - `code`: 退出代码
87pub fn exit_group(code: c_int) -> ! {
88    // TODO: 处理 tid_addr 和 robust_list
89    exit_process(current_task(), code & 0xFF);
90    schedule();
91    unreachable!("exit: exit_task should not return.");
92}
93
94/// 克隆当前任务(线程或进程)
95/// # 参数
96/// - `fn_ptr`: 指向新任务执行函数的指针
97/// - `stack`: 指向新任务栈顶的指针
98/// - `flags`: 克隆选项标志
99/// - `arg`: 传递给新任务执行函数的参数指针
100/// # 返回值
101/// - 成功返回新任务的线程 ID (TID),失败返回负错误码
102pub fn clone(
103    flags: c_ulong,    // a0: clone flags
104    stack: c_ulong,    // a1: child stack pointer
105    ptid: *mut c_int,  // a2: parent_tid pointer
106    _tls: *mut c_void, // a3: TLS pointer
107    ctid: *mut c_int,  // a4: child_tid pointer
108) -> c_int {
109    let requested_flags = if let Some(requested_flags) = CloneFlags::from_bits(flags as usize) {
110        requested_flags
111    } else {
112        return -EINVAL;
113    };
114    if !requested_flags.is_known() {
115        return -EINVAL;
116    }
117    if !requested_flags.is_supported() {
118        return -ENOSYS;
119    }
120    // 根据 clone(2) 的 man page,当指定 CLONE_VM 标志时,必须为子进程提供一个新的栈
121    // 否则父子进程将共享同一个栈,导致栈污染和程序崩溃
122    if requested_flags.contains(CloneFlags::VM) && stack == 0 {
123        return -EINVAL;
124    }
125    let tid = { TASK_MANAGER.lock().allocate_tid() };
126    let (
127        c_pid,
128        c_ppid,
129        c_pgid,
130        space,
131        signal_handlers,
132        blocked,
133        signal,
134        signal_stack,
135        ptf,
136        fd_table,
137        fs,
138        uts,
139        rlimit,
140    ) = {
141        let cpu = current_cpu().lock();
142        let task = cpu.current_task.as_ref().unwrap().lock();
143        (
144            task.pid,
145            task.ppid,
146            task.pgid,
147            task.memory_space
148                .clone()
149                .expect("fork: can only call fork on a user task."),
150            task.signal_handlers.clone(),
151            task.blocked,
152            task.shared_pending.clone(),
153            task.signal_stack.clone(),
154            task.trap_frame_ptr.load(Ordering::SeqCst),
155            task.fd_table.clone(),
156            task.fs.clone(),
157            task.uts_namespace.clone(),
158            task.rlimit.clone(),
159        )
160    };
161    let exit_signal = requested_flags.get_exit_signal();
162    let space = if requested_flags.contains(CloneFlags::VM) {
163        space
164    } else {
165        Arc::new(SpinLock::new(
166            space
167                .lock()
168                .clone_for_fork()
169                .expect("fork: clone memory space failed."),
170        ))
171    };
172    let fd_table = if requested_flags.contains(CloneFlags::FILES) {
173        fd_table
174    } else {
175        Arc::new(fd_table.clone_table())
176    };
177    let fs = if requested_flags.contains(CloneFlags::FS) {
178        fs
179    } else {
180        Arc::new(SpinLock::new(fs.lock().clone()))
181    };
182    let ppid = if requested_flags.contains(CloneFlags::PARENT) {
183        c_ppid
184    } else {
185        c_pid
186    };
187    let pid = if requested_flags.contains(CloneFlags::THREAD) {
188        c_pid
189    } else {
190        tid
191    };
192    let (signal, signal_handler, signal_stack) = if requested_flags.contains(CloneFlags::SIGHAND) {
193        (signal, signal_handlers, signal_stack)
194    } else {
195        (
196            Arc::new(SpinLock::new(SignalPending::empty())),
197            Arc::new(SpinLock::new(SignalHandlerTable::new())),
198            Arc::new(SpinLock::new(StackT::default())),
199        )
200    };
201
202    let kstack_tracker = alloc_contig_frames(4).expect("fork: alloc kstack failed.");
203    let trap_frame_tracker = alloc_frame().expect("fork: alloc trap frame failed");
204    let child_task = TaskStruct::utask_create(
205        tid,
206        pid,
207        ppid,
208        c_pgid,
209        TaskStruct::empty_children(),
210        kstack_tracker,
211        trap_frame_tracker,
212        space,
213        signal_handler,
214        blocked,
215        signal,
216        signal_stack,
217        exit_signal,
218        uts,
219        rlimit,
220        fd_table,
221        fs,
222    );
223
224    if requested_flags.contains(CloneFlags::CHILD_SETTID) {
225        unsafe {
226            write_to_user(ctid, tid as c_int);
227        }
228    }
229    if requested_flags.contains(CloneFlags::PARENT_SETTID) {
230        unsafe {
231            write_to_user(ptid, tid as c_int);
232        }
233    }
234
235    let tf = child_task.trap_frame_ptr.load(Ordering::SeqCst);
236    unsafe {
237        (*tf).set_clone_trap_frame(&*ptf, child_task.kstack_base, stack as usize);
238    }
239    let child_task = child_task.into_shared();
240    current_task()
241        .lock()
242        .children
243        .lock()
244        .push(child_task.clone());
245
246    TASK_MANAGER.lock().add_task(child_task.clone());
247    SCHEDULER.lock().add_task(child_task);
248    tid as c_int
249}
250
251/// 执行一个新程序(execve)
252/// # 参数
253/// - `path`: 可执行文件路径
254/// - `argv`: 命令行参数
255/// - `envp`: 环境变量
256/// TODO: 目前该函数可用但亟待完善
257pub fn execve(
258    path: *const c_char,
259    argv: *const *const c_char,
260    envp: *const *const c_char,
261) -> c_int {
262    // 使用 SumGuard 来安全访问用户空间路径和参数
263    let (path_str, argv_strings, envp_strings) = unsafe {
264        let _guard = SumGuard::new();
265        let path_str = match get_path_safe(path) {
266            Ok(s) => s.to_string(),
267            Err(_) => {
268                return FsError::InvalidArgument.to_errno() as i32;
269            }
270        };
271        let argv_strings = get_args_safe(argv, "argv").unwrap_or_else(|_| Vec::new());
272        let envp_strings = get_args_safe(envp, "envp").unwrap_or_else(|_| Vec::new());
273        (path_str, argv_strings, envp_strings)
274    };
275
276    let data = match crate::vfs::vfs_load_elf(&path_str) {
277        Ok(data) => data,
278        Err(FsError::NotFound) => return -ENOENT,
279        Err(FsError::IsDirectory) => return -EISDIR,
280        Err(_) => return -EIO,
281    };
282
283    let (data, argv_strings, envp_strings) =
284        if data.len() >= 2 && data[0] == b'#' && data[1] == b'!' {
285            if let Ok((path, args)) = parse_hashbang(&data) {
286                let mut new_argv = Vec::new();
287                new_argv.push(path.to_string());
288                // XXX: 目前仅支持单个参数
289                if let Some(arg) = args {
290                    new_argv.push(arg.to_string());
291                }
292                new_argv.push(path_str.clone()); // Clone path_str instead of moving
293                new_argv.extend(argv_strings.iter().skip(1).cloned());
294                let data = match crate::vfs::vfs_load_elf(path) {
295                    Ok(d) => d,
296                    Err(FsError::NotFound) => return -ENOENT,
297                    Err(FsError::IsDirectory) => return -EISDIR,
298                    Err(_) => return -EIO,
299                };
300                (data, new_argv, envp_strings)
301            } else {
302                return -EINVAL;
303            }
304        } else {
305            (data, argv_strings, envp_strings)
306        };
307
308    // // 构造 &str 切片(String 的所有权在本函数内,切片在调用 t.execve 时仍然有效)
309    // let argv_refs: Vec<&str> = argv_strings.iter().map(|s| s.as_str()).collect();
310    // let envp_refs: Vec<&str> = envp_strings.iter().map(|s| s.as_str()).collect();
311
312    // 解析 ELF 并准备新的地址空间(但不切换)
313    let (space, entry, sp, phdr_addr, phnum, phent) = match do_execve_prepare(&data) {
314        Ok(res) => res,
315        Err(e) => return e,
316    };
317
318    // 显式释放 data 缓冲区,避免内存泄漏
319    crate::earlyprintln!(
320        "[execve] Dropping {} byte ELF buffer before switching to user space",
321        data.len()
322    );
323    drop(data);
324
325    // Explicitly drop other stack resources
326    drop(path_str);
327
328    // 切换到新的地址空间并恢复到用户态(此函数不会返回)
329    do_execve_switch(
330        space,
331        entry,
332        sp,
333        argv_strings, // Pass ownership
334        envp_strings, // Pass ownership
335        phdr_addr,
336        phnum,
337        phent,
338    )
339}
340
341/// 等待子进程状态变化(wait4)
342/// # 说明
343/// 状态变化包括:
344///     1. 子进程已终止;
345///     2. 子进程被信号停止;
346///     3. 子进程被信号恢复。
347/// 对于已终止的子进程,执行等待操作可以让系统释放与该子进程关联的资源;
348/// # 参数
349/// - `pid`:
350///     1. > 0 表示需要等待的子进程ID
351///     2. 0 表示等待同一进程组的任意子进程
352///     3. -1 表示等待任意子进程
353///     4. < -1 表示等待进程组ID等于 pid 绝对值的任意子进程
354/// - `wstatus`: 指向存储子进程状态的整数指针
355/// - `options`: 等待选项标志
356/// - `rusage`: 指向存储资源使用情况的 rusage 结构体指针
357/// # 返回值
358/// - 成功返回子进程 ID, 如果设置了 NOHANG 标志且没有满足条件的子进程,则立即返回 0,失败返回负错误码
359/// TODO:
360/// 1. rusage 参数的处理
361/// 2. 信号处理
362/// 3. 错误处理
363pub fn wait4(pid: c_int, wstatus: *mut c_int, options: c_int, _rusage: *mut Rusage) -> c_int {
364    // 阻塞当前任务,直到指定的子任务结束
365    let cur_task = current_cpu().lock().current_task.as_ref().unwrap().clone();
366    let opt = if let Some(opt) = WaitFlags::from_bits(options as usize) {
367        opt
368    } else {
369        return -EINVAL;
370    };
371    let cur_pgid = cur_task.lock().pgid;
372    let match_pid = |child_task: &SharedTask| {
373        match pid {
374            -1 => true,                                           // 匹配所有子进程
375            0 => child_task.lock().pgid == cur_pgid,              // 匹配进程组
376            p if p > 0 => child_task.lock().pid == p as u32,      // 匹配特定 PID
377            p if p < -1 => child_task.lock().pgid == (-p) as u32, // 匹配特定进程组 |pid|
378            _ => unreachable!("wait4: unreachable pid match case."),
379        }
380    };
381    let check_exited = opt.contains(WaitFlags::EXITED)
382        || (!opt.contains(WaitFlags::STOPPED) && !opt.contains(WaitFlags::CONTINUED));
383
384    let zombie: fn(TaskState) -> bool = if check_exited {
385        |ch| ch == TaskState::Zombie
386    } else {
387        |_ch| false
388    };
389    let continued: fn(TaskState) -> bool = if opt.contains(WaitFlags::CONTINUED) {
390        |ch| ch == TaskState::Running
391    } else {
392        |_ch| false
393    };
394    let stopped: fn(TaskState) -> bool = if opt.contains(WaitFlags::STOPPED) {
395        |ch| ch == TaskState::Stopped || ch == TaskState::Zombie
396    } else {
397        |_ch| false
398    };
399    let cond = |ch: &SharedTask| {
400        if !match_pid(ch) {
401            return false;
402        }
403        let state = ch.lock().state;
404        zombie(state) || continued(state) || stopped(state)
405    };
406
407    let task = loop {
408        {
409            let mut t = cur_task.lock();
410            if let Some(res) = t.check_child(cond, !opt.contains(WaitFlags::NOWAIT)) {
411                crate::pr_debug!("wait4: found child pid={}", res.lock().pid);
412                break res;
413            } else {
414                if opt.contains(WaitFlags::NOHANG) {
415                    return 0;
416                }
417            }
418            {
419                let mut wc = t.wait_child.lock();
420                if !wc.contains(&cur_task) {
421                    wc.add_task(cur_task.clone());
422                }
423            }
424            sleep_task_with_guard_and_block(&mut t, cur_task.clone(), true);
425        }
426        // 在没有持有任何锁的情况下调用调度相关操作
427        yield_task();
428    };
429
430    let (tid, state, exit_code) = {
431        let t = task.lock();
432        (t.tid, t.state, t.exit_code)
433    };
434
435    let status = match state {
436        TaskState::Zombie => {
437            // TODO: 处理信号退出的情况
438            WaitStatus::exit_code(exit_code.expect("Zombie must set exit code.") as u8, 0)
439        }
440        TaskState::Stopped => {
441            WaitStatus::stop_code(0) // TODO: 停止信号
442        }
443        TaskState::Running => WaitStatus::continued_code(),
444        _ => {
445            unreachable!("wait4: unexpected task state.")
446        }
447    };
448
449    unsafe {
450        write_to_user(wstatus, status.raw());
451    }
452
453    // 如果子任务是 Zombie 状态,从 TASK_MANAGER 中释放它
454    // 这样 Task 结构体和其拥有的资源(kstack, trap_frame)才会被释放
455    // 当 wait4 使用 WNOWAIT 标志调用时,它不应该回收子进程
456    if state == TaskState::Zombie && !opt.contains(WaitFlags::NOWAIT) {
457        // [FIX] 从父进程的 children 列表中移除该任务
458        // 之前只从 wait_child 移除了,导致 children 列表一直持有引用,造成泄漏
459        // XX: 这是否是必要的修复?
460        {
461            let parent = current_task();
462            let p_lock = parent.lock();
463            let mut children = p_lock.children.lock();
464            let old_len = children.len();
465            children.retain(|c| c.lock().tid != tid);
466            crate::earlyprintln!(
467                "[wait4] Removed from parent.children: {} -> {}",
468                old_len,
469                children.len()
470            );
471        }
472        TASK_MANAGER.lock().release_task(task);
473    }
474
475    tid as c_int
476}
477
478/// 获取当前任务的进程 ID
479/// # 返回值:
480/// - 进程 ID
481pub fn get_pid() -> c_int {
482    current_task().lock().pid as c_int
483}
484
485/// 获取当前任务的父进程 ID
486/// # 返回值:
487/// - 父进程 ID, 该进程要么是创建该进程的进程, 要么是重新归属的父进程
488pub fn get_ppid() -> c_int {
489    current_task().lock().ppid as c_int
490}
491
492/// 获取进程组 ID
493///
494/// # 参数
495/// - `pid`: 进程 ID。如果为 0,返回调用进程的 PGID
496///
497/// # 返回值
498/// - 成功: 返回进程组 ID
499/// - 失败: 返回 -ESRCH (进程不存在或 pid 为负数)
500pub fn get_pgid(pid: c_int) -> c_int {
501    use crate::uapi::errno::ESRCH;
502
503    if pid == 0 {
504        return current_task().lock().pgid as c_int;
505    }
506
507    if pid < 0 {
508        return -ESRCH as c_int;
509    }
510
511    let manager = TASK_MANAGER.lock();
512    let task_opt = manager.get_task(pid as u32);
513    drop(manager);
514
515    match task_opt {
516        Some(task) => task.lock().pgid as c_int,
517        None => -ESRCH as c_int,
518    }
519}
520
521/// 设置进程组 ID
522pub fn set_pgid(pid: c_int, pgid: c_int) -> c_int {
523    use crate::uapi::errno::{EACCES, EINVAL, EPERM, ESRCH};
524
525    let current = current_task();
526    let current_locked = current.lock();
527    let current_pid = current_locked.tid as c_int;
528    let current_ppid = current_locked.ppid as c_int;
529    drop(current_locked);
530
531    let target_pid = if pid == 0 { current_pid } else { pid };
532    let target_pgid = if pgid == 0 { target_pid } else { pgid };
533
534    if target_pgid < 0 {
535        return -EINVAL as c_int;
536    }
537
538    let manager = TASK_MANAGER.lock();
539    let task_opt = manager.get_task(target_pid as u32);
540    drop(manager);
541
542    let task = match task_opt {
543        Some(t) => t,
544        None => return -ESRCH as c_int,
545    };
546
547    let mut task_locked = task.lock();
548
549    // 权限检查:目标进程必须是调用者本身或其子进程
550    if target_pid != current_pid && task_locked.ppid as c_int != current_pid {
551        return -ESRCH as c_int;
552    }
553
554    // 不能更改已经是会话领导者的进程(简化检查:pgid == tid)
555    if task_locked.pgid == task_locked.tid {
556        return -EPERM as c_int;
557    }
558
559    // 设置进程组 ID
560    task_locked.pgid = target_pgid as u32;
561    0
562}
563
564/// 获取资源限制
565/// # 参数
566/// - `resource`: 资源限制 ID
567/// - `rlim`: 指向 rlimit 结构体的指针, 用于存储获取到的资源限制
568/// # 返回值
569/// - 成功返回 0, 失败返回负错误码
570pub fn getrlimit(resource: c_int, rlim: *mut Rlimit) -> c_int {
571    if resource as usize >= RLIM_NLIMITS {
572        return -EINVAL;
573    }
574    let rlimit = current_task().lock().rlimit.lock().limits[resource as usize];
575    unsafe {
576        write_to_user(rlim, rlimit);
577    }
578    0
579    // TODO: EPERM 和 EFAULT
580}
581
582/// 设置资源限制
583/// # 参数
584/// - `resource`: 资源限制 ID
585/// - `rlim`: 指向 rlimit 结构体的指针, 包含要设置的资源限制
586/// # 返回值
587/// - 成功返回 0, 失败返回负错误码
588pub fn setrlimit(resource: c_int, rlim: *const Rlimit) -> c_int {
589    if resource as usize >= RLIM_NLIMITS {
590        return -EINVAL;
591    }
592    let new_limit = unsafe { read_from_user(rlim) };
593    if new_limit.rlim_cur > new_limit.rlim_max {
594        return -EINVAL;
595    }
596    {
597        let rlimit_lock = current_task().lock().rlimit.clone();
598        rlimit_lock.lock().limits[resource as usize] = new_limit;
599    }
600    0
601    // TODO: EPERM, EPERM 和 EFAULT
602}
603
604/// 获取或设置资源限制
605/// # 参数
606/// - `pid`: 目标进程 ID, 为 0 表示当前进程
607/// - `resource`: 资源限制 ID
608/// - `new_limit`: 指向 rlimit 结构体的指针, 包含要设置的资源限制, 若不设置则为 NULL
609/// - `old_limit`: 指向 rlimit 结构体的指针, 用于存储获取到的资源限制, 若不获取则为 NULL
610/// # 返回值
611/// - 成功返回 0, 失败返回负错误码
612pub fn prlimit(
613    pid: c_int,
614    resource: c_int,
615    new_limit: *const Rlimit,
616    old_limit: *mut Rlimit,
617) -> c_int {
618    if resource as usize >= RLIM_NLIMITS {
619        return -EINVAL;
620    }
621    let target_task = if pid == 0 {
622        current_task()
623    } else {
624        let tm = TASK_MANAGER.lock();
625        match tm.get_task(pid as u32) {
626            Some(t) => t,
627            None => return -ESRCH,
628        }
629    };
630
631    if !old_limit.is_null() {
632        let rlimit = target_task.lock().rlimit.lock().limits[resource as usize];
633        unsafe {
634            write_to_user(old_limit, rlimit);
635        }
636    }
637
638    if !new_limit.is_null() {
639        let new_rlim = unsafe { read_from_user(new_limit) };
640        if new_rlim.rlim_cur > new_rlim.rlim_max {
641            return -EINVAL;
642        }
643        let rlimit_lock = target_task.lock().rlimit.clone();
644        rlimit_lock.lock().limits[resource as usize] = new_rlim;
645    }
646
647    0
648    // TODO: EPERM, EPERM 和 EFAULT
649}
650
651/// 高精度睡眠(纳秒级别)
652/// # 参数
653/// - `duration`: 指向 TimeSpec 结构体的指针, 包含睡眠的时间
654/// - `rem`: 指向 TimeSpec 结构体的指针, 用于存储剩余的睡眠时间, 可为 NULL
655/// # 返回值
656/// - 成功返回 0, 失败返回负错误码
657pub fn nanosleep(duration: *const TimeSpec, rem: *mut TimeSpec) -> c_int {
658    let req = unsafe { read_from_user(duration) };
659    if req.tv_sec == 0 && req.tv_nsec == 0 {
660        return 0;
661    }
662    if req.tv_sec < 0 || req.tv_nsec < 0 || req.tv_nsec > 999999999 {
663        return -EINVAL;
664    }
665    let mut result = 0;
666    let task = current_task();
667    let trigger = get_time() + req.into_freq(clock_freq());
668
669    let mut timer_q = TIMER_QUEUE.lock();
670    timer_q.push(trigger, task.clone());
671    sleep_task_with_block(task.clone(), true);
672    drop(timer_q);
673    yield_task();
674
675    // 被唤醒后(可能是超时,也可能是信号),必须确保将任务从定时器队列中清理掉
676    // 如果是超时唤醒,pop_due_task 已经移除了
677    // 如果是信号唤醒,任务还在队列中,需要手动移除以避免 Arc 泄漏
678    TIMER_QUEUE.lock().remove_task(&task);
679
680    if !rem.is_null() {
681        let dur = trigger.saturating_sub(get_time());
682        let remaining_ticks = if dur > 0 {
683            // XXX: 提前唤醒是否一定是因为信号?
684            result = -EINTR;
685            dur
686        } else {
687            0
688        };
689        let rem_ts = TimeSpec::from_freq(remaining_ticks, clock_freq());
690        unsafe {
691            write_to_user(rem, rem_ts);
692        }
693    }
694
695    result
696    // TODO: EFAULT
697}
698
699pub fn gettid() -> c_int {
700    current_task().lock().tid as c_int
701}
702
703/// 基于时钟的高精度睡眠
704/// # 参数
705/// - `clk_id`: 时钟 ID
706/// - `flags`: 睡眠选项标志
707/// - `req`: 指向 TimeSpec 结构体的指针, 包含睡眠的时间
708/// - `rem`: 指向 TimeSpec 结构体的指针, 用于存储剩余的睡眠时间, 可为 NULL
709/// # 返回值
710/// - 成功返回 0, 失败返回负错误码
711pub fn clock_nanosleep(
712    clk_id: c_int,
713    flags: c_int,
714    req: *const TimeSpec,
715    rem: *mut TimeSpec,
716) -> c_int {
717    let time_req = unsafe { read_from_user(req) };
718    let is_abstime = (flags & TIMER_ABSTIME) != 0;
719    let sleep_ticks = time_req.into_freq(clock_freq());
720    let trigger = if is_abstime {
721        sleep_ticks
722    } else {
723        let now = match clk_id {
724            CLOCK_REALTIME => REALTIME.read().into_freq(clock_freq()),
725            CLOCK_MONOTONIC => get_time(),
726            CLOCK_TAI | CLOCK_BOOTTIME | CLOCK_PROCESS_CPUTIME_ID => return -ENOSYS,
727            _ => return -EINVAL,
728        };
729        now.saturating_add(sleep_ticks)
730    };
731
732    let mut result = 0;
733    let task = current_task();
734
735    let mut timer_q = TIMER_QUEUE.lock();
736    timer_q.push(trigger, task.clone());
737    sleep_task_with_block(task.clone(), true);
738    drop(timer_q);
739    yield_task();
740
741    // 同 sys_nanosleep,防止信号唤醒导致的 Arc 泄漏
742    TIMER_QUEUE.lock().remove_task(&task);
743
744    if !rem.is_null() {
745        let dur = trigger.saturating_sub(get_time());
746        let remaining_ticks = if dur > 0 {
747            // XXX: 提前唤醒是否一定是因为信号?
748            result = -EINTR;
749            dur
750        } else {
751            0
752        };
753        let rem_ts = TimeSpec::from_freq(remaining_ticks, clock_freq());
754        unsafe {
755            write_to_user(rem, rem_ts);
756        }
757    }
758
759    result
760}
761
762/// 获取间隔定时器的当前值
763/// # 参数
764/// - `which`: 定时器 ID
765/// - `curr_value`: 指向 Itimerval 结构体的指针, 用于存储当前定时器值
766/// # 返回值
767/// - 成功返回 0, 失败返回负错误码
768pub fn getitimer(which: c_int, curr_value: *mut Itimerval) -> c_int {
769    match which {
770        ITIMER_REAL | ITIMER_VIRTUAL | ITIMER_PROF => {}
771        _ => return -EINVAL,
772    }
773    let sig = match which {
774        ITIMER_REAL => NUM_SIGALRM,
775        ITIMER_VIRTUAL => NUM_SIGVTALRM,
776        ITIMER_PROF => NUM_SIGPROF,
777        _ => unreachable!("getitimer: unreachable which case."),
778    };
779    let mut val = Itimerval::zero();
780    if let Some(timer) = TIMER.lock().find_entry(&current_task(), sig) {
781        let now = get_time();
782        let remaining = if *timer.0 > now { *timer.0 - now } else { 0 };
783        let it_value = TimeSpec::from_freq(remaining, clock_freq()).to_timeval();
784        let it_interval = timer.1.it_interval.to_timeval();
785        val = Itimerval {
786            it_value,
787            it_interval,
788        };
789    }
790    unsafe {
791        write_to_user(curr_value, val);
792    }
793    0
794}
795
796/// 设置间隔定时器的值
797/// # 参数
798/// - `which`: 定时器 ID
799/// - `new_value`: 指向 Itimerval 结构体的指针, 包含要设置的定时器值
800/// - `old_value`: 指向 Itimerval 结构体的指针, 用于存储旧的定时器值, 可为 NULL
801/// # 返回值
802/// - 成功返回 0, 失败返回负错误码
803pub fn setitimer(which: c_int, new_value: *const Itimerval, old_value: *mut Itimerval) -> c_int {
804    match which {
805        ITIMER_REAL | ITIMER_VIRTUAL | ITIMER_PROF => {}
806        _ => return -EINVAL,
807    }
808    let sig = match which {
809        ITIMER_REAL => NUM_SIGALRM,
810        ITIMER_VIRTUAL => NUM_SIGVTALRM,
811        ITIMER_PROF => NUM_SIGPROF,
812        _ => unreachable!("setitimer: unreachable which case."),
813    };
814
815    let mut binding = TIMER.lock();
816    let new_itimer = unsafe { read_from_user(new_value) };
817    if !new_itimer.it_value.is_zero() {
818        let trigger = get_time() + new_itimer.it_value.into_freq(clock_freq());
819        let interval = new_itimer.it_interval.to_timespec();
820        let entry = TimerEntry {
821            task: current_task(),
822            sig,
823            it_interval: interval,
824        };
825        binding.push(trigger, entry);
826    }
827    if !old_value.is_null() {
828        let mut val = Itimerval::zero();
829        if let Some(timer) = binding.find_entry(&current_task(), sig) {
830            let now = get_time();
831            let remaining = if *timer.0 > now { *timer.0 - now } else { 0 };
832            let it_value = TimeSpec::from_freq(remaining, clock_freq()).to_timeval();
833            let it_interval = timer.1.it_interval.to_timeval();
834            val = Itimerval {
835                it_value,
836                it_interval,
837            };
838        }
839        unsafe {
840            write_to_user(old_value, val);
841        }
842    }
843
844    0
845}
846
847/// Futex 系统调用实现
848/// # 参数
849/// - `uaddr`: 指向用户空间中 futex 变量的指针
850/// - `op`: 操作码和标志
851/// - `val`: 操作相关的值
852/// - `_timeout`: 指向 TimeSpec 结构体的指针, 用于指定超时时间
853/// - `_uaddr2`: 指向用户空间中第二个 futex 变量的指针
854/// - `_val3`: 额外的操作相关值
855/// # 返回值
856/// - 成功返回 0, 失败返回负错误码
857pub fn futex(
858    uaddr: *mut u32,
859    op: c_int,
860    val: u32,
861    timeout: *const TimeSpec,
862    _uaddr2: *mut u32,
863    _val3: u32,
864) -> c_int {
865    let _private = (op & FUTEX_PRIVATE as c_int) != 0; // TODO: 目前不区分 PRIVATE 和 SHARED
866    let realtime = (op & FUTEX_CLOCK_REALTIME as c_int) != 0;
867    let op = op & !(FUTEX_PRIVATE as c_int) & !(FUTEX_CLOCK_REALTIME as c_int);
868    // HACK: 其实只需要锁定与 uaddr 对应的 Futex 等待队列
869    let mut fm = FUTEX_MANAGER.lock();
870    match op as u32 {
871        FUTEX_WAIT => {
872            // 必须保证获 取锁 → 读取用户数据 → 比较 → 释放锁 整个序列是原子的
873            let user_val = unsafe { read_from_user(uaddr) };
874            let memory_space = current_task()
875                .lock()
876                .memory_space
877                .as_ref()
878                .expect("futex: current task has no memory space.")
879                .clone();
880            let paddr = if let Some(paddr) = memory_space
881                .lock()
882                .translate(Vaddr::from_usize(uaddr as usize))
883            {
884                paddr.as_usize()
885            } else {
886                return -EFAULT;
887            };
888            if user_val != val as u32 {
889                return -EAGAIN;
890            }
891
892            let task = current_task();
893            let waitq = fm.get_wait_queue(paddr);
894            waitq.sleep(task.clone());
895            sleep_task_with_block(task.clone(), true);
896
897            if !timeout.is_null() {
898                let ts = unsafe { read_from_user(timeout) };
899                if ts.tv_sec < 0 || ts.tv_nsec < 0 || ts.tv_nsec > 999999999 {
900                    return -EINVAL;
901                }
902                let sleep_ticks = ts.into_freq(clock_freq());
903                let trigger = if realtime {
904                    let now = realtime_now().into_freq(clock_freq());
905                    now.saturating_add(sleep_ticks)
906                } else {
907                    let now = get_time();
908                    now.saturating_add(sleep_ticks)
909                };
910                TIMER_QUEUE.lock().push(trigger, task.clone());
911                drop(fm);
912                yield_task();
913                if TIMER_QUEUE.lock().remove_task(&task).is_none() {
914                    // 超时唤醒
915                    let mut fm = FUTEX_MANAGER.lock();
916                    let waitq = fm.get_wait_queue(paddr);
917                    // 虽然任务已经被唤醒, 但仍然需要从等待队列中移除
918                    waitq.remove_task(&task);
919                    return -ETIMEDOUT;
920                }
921            } else {
922                drop(fm);
923                yield_task();
924            }
925            if signal_pending(&task) {
926                // 信号唤醒
927                let mut fm = FUTEX_MANAGER.lock();
928                let waitq = fm.get_wait_queue(paddr);
929                waitq.remove_task(&task);
930                return -EINTR;
931            }
932            // 正常唤醒
933            // NOTE: 此时任务已经不在等待队列中
934            0
935        }
936        FUTEX_WAKE => {
937            let mut wake_count = 0;
938            let paddr = {
939                let memory_space = current_task()
940                    .lock()
941                    .memory_space
942                    .as_ref()
943                    .expect("futex: current task has no memory space.")
944                    .clone();
945                if let Some(paddr) = memory_space
946                    .lock()
947                    .translate(Vaddr::from_usize(uaddr as usize))
948                {
949                    paddr.as_usize()
950                } else {
951                    return -EFAULT;
952                }
953            };
954            let mut fm = FUTEX_MANAGER.lock();
955            let waitq = fm.get_wait_queue(paddr);
956            for _ in 0..val {
957                waitq.wake_up_one();
958                wake_count += 1;
959            }
960            wake_count
961        }
962        _ => -ENOSYS,
963    }
964}
965
966//    long syscall(SYS_get_robust_list, int pid,
967//                 struct robust_list_head **head_ptr, size_t *sizep);
968//    long syscall(SYS_set_robust_list,
969//                 struct robust_list_head *head, size_t size);
970
971/// 设置线程 ID 地址
972/// # 参数
973/// - `tidptr`: 指向存储线程 ID 的用户空间地址
974/// # 返回值
975/// - 返回当前线程的线程 ID (TID)
976pub fn set_tid_address(tidptr: *mut c_int) -> c_int {
977    let task = current_task();
978    task.lock().clear_child_tid = tidptr as usize;
979    current_task().lock().tid as c_int
980}
981
982/// 获取线程的 robust futex 列表头指针和大小
983/// # 参数
984/// - `pid`: 目标进程 ID, 为 0 表示当前进程
985/// - `head_ptr`: 指向存储 robust futex 列表头指针的用户空间地址
986/// - `sizep`: 指向存储 robust futex 列表大小的用户空间地址
987/// # 返回值
988/// - 成功返回 0, 失败返回负错误码
989pub fn get_robust_list(pid: c_int, head_ptr: *mut *mut RobustListHead, sizep: *mut SizeT) -> c_int {
990    let task = if pid == 0 {
991        current_task()
992    } else {
993        let tm = TASK_MANAGER.lock();
994        match tm.get_task(pid as u32) {
995            Some(t) => t,
996            None => return -ESRCH,
997        }
998    };
999    let (head, size) = {
1000        let t = task.lock();
1001        let head = match t.robust_list {
1002            Some(h) => h as *mut RobustListHead,
1003            None => core::ptr::null_mut(),
1004        };
1005        let size = size_of::<RobustListHead>() as SizeT;
1006        (head, size)
1007    };
1008    unsafe {
1009        write_to_user(head_ptr, head);
1010        write_to_user(sizep, size);
1011    }
1012    0
1013}
1014
1015/// 设置线程的 robust futex 列表头指针
1016/// # 参数
1017/// - `head`: 指向 robust futex 列表头的指针
1018/// - `size`: robust futex 列表的大小
1019/// # 返回值
1020/// - 成功返回 0, 失败返回负错误码
1021pub fn set_robust_list(head: *const RobustListHead, size: SizeT) -> c_int {
1022    if size != size_of::<RobustListHead>() as SizeT {
1023        return -EINVAL;
1024    }
1025    let task = current_task();
1026    task.lock().robust_list = Some(head as usize);
1027    0
1028}
1029
1030/// 创建一个新的会话并设置进程组 ID
1031/// # 返回值
1032/// - 成功返回新会话的进程组 ID, 失败返回负错误码
1033pub fn setsid() -> c_int {
1034    let task = current_task();
1035    let mut t = task.lock();
1036    if t.pid == t.pgid {
1037        return -EPERM;
1038    }
1039    let new_pgid = t.pid;
1040    t.pgid = new_pgid;
1041    new_pgid as c_int
1042}
1043
1044/// 辅助函数:解析 Hashbang 行
1045fn parse_hashbang(data: &[u8]) -> Result<(&str, Option<&str>), ()> {
1046    // 查找第一个换行符 ('\n'),只读取第一行
1047    let line_end = data.iter().position(|&b| b == b'\n').unwrap_or(data.len());
1048    // 跳过开头的空格和制表符
1049    let line_start = data[2..line_end]
1050        .iter()
1051        .position(|&b| b != b' ' && b != b'\t')
1052        .unwrap_or(line_end - 2)
1053        + 2;
1054    let line = &data[line_start..line_end];
1055
1056    // 假设用空格分隔解释器路径和可选参数
1057    let parts: Vec<&[u8]> = line
1058        .split(|&b| b == b' ' || b == b'\t')
1059        .filter(|p| !p.is_empty()) // 过滤空串
1060        .collect();
1061
1062    if parts.is_empty() {
1063        return Err(()); // 格式错误或只包含 #!
1064    }
1065
1066    // 解释器路径
1067    let interpreter_path = core::str::from_utf8(parts[0]).map_err(|_| ())?;
1068
1069    // 可选参数
1070    let interpreter_arg = parts
1071        .get(1)
1072        .map(|p| core::str::from_utf8(p))
1073        .transpose()
1074        .map_err(|_| ())?;
1075
1076    Ok((interpreter_path, interpreter_arg))
1077}
1078
1079/// 执行一个新程序(execve)的准备阶段:解析 ELF 并创建新的地址空间
1080fn do_execve_prepare(
1081    data: &[u8],
1082) -> Result<
1083    (
1084        Arc<SpinLock<MemorySpace>>,
1085        usize,
1086        usize,
1087        usize,
1088        usize,
1089        usize,
1090    ),
1091    c_int,
1092> {
1093    let (space, entry, sp, phdr_addr, phnum, phent) = match MemorySpace::from_elf(data) {
1094        Ok(res) => res,
1095        Err(_) => return Err(-ENOEXEC),
1096    };
1097
1098    let space = Arc::new(SpinLock::new(space));
1099    Ok((space, entry, sp, phdr_addr, phnum, phent))
1100}
1101
1102/// 执行一个新程序(execve)的切换阶段:切换地址空间并恢复到用户态
1103/// 注意:此函数不会返回!
1104fn do_execve_switch(
1105    space: Arc<SpinLock<MemorySpace>>,
1106    entry: usize,
1107    sp: usize,
1108    argv: Vec<alloc::string::String>,
1109    envp: Vec<alloc::string::String>,
1110    phdr_addr: usize,
1111    phnum: usize,
1112    phent: usize,
1113) -> c_int {
1114    let task = current_task();
1115
1116    task.lock().fd_table.close_exec();
1117
1118    // 换掉当前任务的地址空间,e.g. 切换 satp
1119    current_cpu().lock().switch_space(space.clone());
1120
1121    // 此时在syscall处理的中断上下文中,中断已关闭,直接修改当前任务的trapframe
1122    // 注意:space 被 clone 进了 execve,所以这里的 space 变量仍然有效
1123    {
1124        // 构造 &str 切片供 execve 使用 (Inner scope to ensure borrows end)
1125        let argv_refs: Vec<&str> = argv.iter().map(|s| s.as_str()).collect();
1126        let envp_refs: Vec<&str> = envp.iter().map(|s| s.as_str()).collect();
1127
1128        let mut t = task.lock();
1129        t.execve(
1130            space.clone(),
1131            entry,
1132            sp,
1133            argv_refs.as_slice(),
1134            envp_refs.as_slice(),
1135            phdr_addr,
1136            phnum,
1137            phent,
1138        );
1139    } // argv_refs/envp_refs dropped here, ending borrow of argv/envp
1140
1141    let tfp = task.lock().trap_frame_ptr.load(Ordering::SeqCst);
1142
1143    // Explicitly drop all owned resources before diverging
1144    drop(argv);
1145    drop(envp);
1146    drop(space); // Drop the Arc<MemorySpace> passed in
1147    drop(task); // Drop current task ref
1148
1149    // SAFETY: tfp 指向的内存已经被分配且由当前任务拥有
1150    // 直接按 trapframe 状态恢复并 sret 到用户态
1151    unsafe {
1152        restore(&*tfp);
1153    }
1154    -1
1155}