// SPDX-License-Identifier: MPL-2.0 #![expect(dead_code)] use ostd::{ cpu::{context::UserContext, CpuSet}, sync::RwArc, task::Task, }; use super::{thread_table, PosixThread, ThreadLocal}; use crate::{ fs::{file_table::FileTable, thread_info::ThreadFsInfo}, prelude::*, process::{ posix_thread::name::ThreadName, signal::{sig_mask::AtomicSigMask, sig_queues::SigQueues}, Credentials, Process, }, sched::{Nice, SchedPolicy}, thread::{task, Thread, Tid}, time::{clocks::ProfClock, TimerManager}, }; /// The builder to build a posix thread pub struct PosixThreadBuilder { // The essential part tid: Tid, user_ctx: Arc, process: Weak, credentials: Credentials, // Optional part thread_name: Option, set_child_tid: Vaddr, clear_child_tid: Vaddr, file_table: Option>, fs: Option>, sig_mask: AtomicSigMask, sig_queues: SigQueues, sched_policy: SchedPolicy, } impl PosixThreadBuilder { pub fn new(tid: Tid, user_ctx: Arc, credentials: Credentials) -> Self { Self { tid, user_ctx, process: Weak::new(), credentials, thread_name: None, set_child_tid: 0, clear_child_tid: 0, file_table: None, fs: None, sig_mask: AtomicSigMask::new_empty(), sig_queues: SigQueues::new(), sched_policy: SchedPolicy::Fair(Nice::default()), } } pub fn process(mut self, process: Weak) -> Self { self.process = process; self } pub fn thread_name(mut self, thread_name: Option) -> Self { self.thread_name = thread_name; self } pub fn set_child_tid(mut self, set_child_tid: Vaddr) -> Self { self.set_child_tid = set_child_tid; self } pub fn clear_child_tid(mut self, clear_child_tid: Vaddr) -> Self { self.clear_child_tid = clear_child_tid; self } pub fn file_table(mut self, file_table: RwArc) -> Self { self.file_table = Some(file_table); self } pub fn fs(mut self, fs: Arc) -> Self { self.fs = Some(fs); self } pub fn sig_mask(mut self, sig_mask: AtomicSigMask) -> Self { self.sig_mask = sig_mask; self } pub fn sched_policy(mut self, sched_policy: SchedPolicy) -> Self { self.sched_policy = sched_policy; self } pub fn build(self) -> Arc { let Self { tid, user_ctx, process, credentials, thread_name, set_child_tid, clear_child_tid, file_table, fs, sig_mask, sig_queues, sched_policy, } = self; let file_table = file_table.unwrap_or_else(|| RwArc::new(FileTable::new_with_stdio())); let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default())); Arc::new_cyclic(|weak_task| { let root_vmar = process .upgrade() .map(|process| process.lock_root_vmar().unwrap().dup().unwrap()); let posix_thread = { let prof_clock = ProfClock::new(); let virtual_timer_manager = TimerManager::new(prof_clock.user_clock().clone()); let prof_timer_manager = TimerManager::new(prof_clock.clone()); PosixThread { process, tid, name: Mutex::new(thread_name), credentials, file_table: file_table.clone_ro(), fs, sig_mask, sig_queues, signalled_waker: SpinLock::new(None), prof_clock, virtual_timer_manager, prof_timer_manager, } }; let cpu_affinity = CpuSet::new_full(); let thread = Arc::new(Thread::new( weak_task.clone(), posix_thread, cpu_affinity, sched_policy, )); let thread_local = ThreadLocal::new(set_child_tid, clear_child_tid, root_vmar, file_table); thread_table::add_thread(tid, thread.clone()); task::create_new_user_task(user_ctx, thread, thread_local) }) } }