thread.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. use super::{
  2. signal::{RaiseResult, Signal, SignalList},
  3. Process, ProcessList, WaitType,
  4. };
  5. use crate::{
  6. kernel::{
  7. interrupt::default_irq_handler,
  8. syscall::{syscall_handlers, SyscallHandler},
  9. task::{clone::CloneArgs, CloneFlags},
  10. timer::timer_interrupt,
  11. user::UserPointerMut,
  12. vfs::{filearray::FileArray, FsContext},
  13. },
  14. prelude::*,
  15. };
  16. use alloc::sync::Arc;
  17. use atomic_unique_refcell::AtomicUniqueRefCell;
  18. use core::{
  19. future::Future,
  20. pin::Pin,
  21. ptr::NonNull,
  22. sync::atomic::{AtomicBool, Ordering},
  23. task::{Context, Poll, Waker},
  24. };
  25. use eonix_hal::{
  26. fpu::FpuState,
  27. processor::{UserTLS, CPU},
  28. traits::{
  29. fault::Fault,
  30. fpu::RawFpuState as _,
  31. trap::{IrqState as _, RawTrapContext, TrapReturn, TrapType},
  32. },
  33. trap::{disable_irqs_save, TrapContext},
  34. };
  35. use eonix_mm::address::{Addr as _, VAddr};
  36. use eonix_runtime::run::{Contexted, Run, RunState};
  37. use eonix_sync::AsProofMut as _;
  38. use pointers::BorrowedArc;
  39. #[eonix_percpu::define_percpu]
  40. static CURRENT_THREAD: Option<NonNull<Thread>> = None;
  41. pub struct ThreadRunnable<F: Future> {
  42. thread: Arc<Thread>,
  43. future: F,
  44. }
  45. pub struct ThreadBuilder {
  46. tid: Option<u32>,
  47. name: Option<Arc<[u8]>>,
  48. process: Option<Arc<Process>>,
  49. files: Option<Arc<FileArray>>,
  50. fs_context: Option<Arc<FsContext>>,
  51. signal_list: Option<SignalList>,
  52. tls: Option<UserTLS>,
  53. set_child_tid: Option<usize>,
  54. clear_child_tid: Option<usize>,
  55. trap_ctx: Option<TrapContext>,
  56. fpu_state: Option<FpuState>,
  57. }
  58. #[derive(Debug)]
  59. struct ThreadInner {
  60. /// Thread name
  61. name: Arc<[u8]>,
  62. /// Thread TLS
  63. tls: Option<UserTLS>,
  64. /// User pointer
  65. /// Store child thread's tid when child thread returns to user space.
  66. set_child_tid: Option<usize>,
  67. clear_child_tid: Option<usize>,
  68. }
  69. pub struct Thread {
  70. pub tid: u32,
  71. pub process: Arc<Process>,
  72. pub files: Arc<FileArray>,
  73. pub fs_context: Arc<FsContext>,
  74. pub signal_list: SignalList,
  75. pub trap_ctx: AtomicUniqueRefCell<TrapContext>,
  76. pub fpu_state: AtomicUniqueRefCell<FpuState>,
  77. pub dead: AtomicBool,
  78. inner: Spin<ThreadInner>,
  79. }
  80. impl ThreadBuilder {
  81. pub fn new() -> Self {
  82. Self {
  83. tid: None,
  84. name: None,
  85. process: None,
  86. files: None,
  87. fs_context: None,
  88. signal_list: None,
  89. tls: None,
  90. set_child_tid: None,
  91. clear_child_tid: None,
  92. trap_ctx: None,
  93. fpu_state: None,
  94. }
  95. }
  96. pub fn tid(mut self, tid: u32) -> Self {
  97. self.tid = Some(tid);
  98. self
  99. }
  100. pub fn name(mut self, name: Arc<[u8]>) -> Self {
  101. self.name = Some(name);
  102. self
  103. }
  104. pub fn process(mut self, process: Arc<Process>) -> Self {
  105. self.process = Some(process);
  106. self
  107. }
  108. pub fn files(mut self, files: Arc<FileArray>) -> Self {
  109. self.files = Some(files);
  110. self
  111. }
  112. pub fn fs_context(mut self, fs_context: Arc<FsContext>) -> Self {
  113. self.fs_context = Some(fs_context);
  114. self
  115. }
  116. pub fn signal_list(mut self, signal_list: SignalList) -> Self {
  117. self.signal_list = Some(signal_list);
  118. self
  119. }
  120. pub fn tls(mut self, tls: Option<UserTLS>) -> Self {
  121. self.tls = tls;
  122. self
  123. }
  124. pub fn set_child_tid(mut self, set_child_tid: Option<usize>) -> Self {
  125. self.set_child_tid = set_child_tid;
  126. self
  127. }
  128. pub fn clear_child_tid(mut self, clear_child_tid: Option<usize>) -> Self {
  129. self.clear_child_tid = clear_child_tid;
  130. self
  131. }
  132. pub fn trap_ctx(mut self, trap_ctx: TrapContext) -> Self {
  133. self.trap_ctx = Some(trap_ctx);
  134. self
  135. }
  136. pub fn fpu_state(mut self, fpu_state: FpuState) -> Self {
  137. self.fpu_state = Some(fpu_state);
  138. self
  139. }
  140. pub fn entry(mut self, entry: VAddr, stack_pointer: VAddr) -> Self {
  141. let mut trap_ctx = TrapContext::new();
  142. trap_ctx.set_user_mode(true);
  143. trap_ctx.set_program_counter(entry.addr());
  144. trap_ctx.set_stack_pointer(stack_pointer.addr());
  145. trap_ctx.set_interrupt_enabled(true);
  146. self.trap_ctx = Some(trap_ctx);
  147. self
  148. }
  149. /// Clone the thread from another thread.
  150. pub fn clone_from(self, thread: &Thread, clone_args: &CloneArgs) -> KResult<Self> {
  151. let inner = thread.inner.lock();
  152. let mut trap_ctx = thread.trap_ctx.borrow().clone();
  153. trap_ctx.set_user_return_value(0);
  154. #[cfg(target_arch = "riscv64")]
  155. {
  156. let pc = trap_ctx.get_program_counter();
  157. trap_ctx.set_program_counter(pc + 4);
  158. }
  159. if let Some(sp) = clone_args.sp {
  160. trap_ctx.set_stack_pointer(sp.get());
  161. }
  162. let fs_context = if clone_args.flags.contains(CloneFlags::CLONE_FS) {
  163. FsContext::new_shared(&thread.fs_context)
  164. } else {
  165. FsContext::new_cloned(&thread.fs_context)
  166. };
  167. let files = if clone_args.flags.contains(CloneFlags::CLONE_FILES) {
  168. FileArray::new_shared(&thread.files)
  169. } else {
  170. FileArray::new_cloned(&thread.files)
  171. };
  172. let signal_list = if clone_args.flags.contains(CloneFlags::CLONE_SIGHAND) {
  173. SignalList::new_shared(&thread.signal_list)
  174. } else {
  175. SignalList::new_cloned(&thread.signal_list)
  176. };
  177. Ok(self
  178. .files(files)
  179. .fs_context(fs_context)
  180. .signal_list(signal_list)
  181. .name(inner.name.clone())
  182. .tls(clone_args.tls.clone())
  183. .set_child_tid(clone_args.set_tid_ptr)
  184. .clear_child_tid(clone_args.clear_tid_ptr)
  185. .trap_ctx(trap_ctx)
  186. .fpu_state(thread.fpu_state.borrow().clone()))
  187. }
  188. pub fn build(self, process_list: &mut ProcessList) -> Arc<Thread> {
  189. let tid = self.tid.expect("TID is not set");
  190. let name = self.name.expect("Name is not set");
  191. let process = self.process.expect("Process is not set");
  192. let files = self.files.unwrap_or_else(|| FileArray::new());
  193. let fs_context = self
  194. .fs_context
  195. .unwrap_or_else(|| FsContext::global().clone());
  196. let signal_list = self.signal_list.unwrap_or_else(|| SignalList::new());
  197. let trap_ctx = self.trap_ctx.expect("TrapContext is not set");
  198. let fpu_state = self.fpu_state.unwrap_or_else(FpuState::new);
  199. signal_list.clear_pending();
  200. let thread = Arc::new(Thread {
  201. tid,
  202. process: process.clone(),
  203. files,
  204. fs_context,
  205. signal_list,
  206. trap_ctx: AtomicUniqueRefCell::new(trap_ctx),
  207. fpu_state: AtomicUniqueRefCell::new(fpu_state),
  208. dead: AtomicBool::new(false),
  209. inner: Spin::new(ThreadInner {
  210. name,
  211. tls: self.tls,
  212. set_child_tid: self.set_child_tid,
  213. clear_child_tid: self.clear_child_tid,
  214. }),
  215. });
  216. process_list.add_thread(&thread);
  217. process.add_thread(&thread, process_list.prove_mut());
  218. thread
  219. }
  220. }
  221. impl Thread {
  222. pub fn current<'lt>() -> BorrowedArc<'lt, Self> {
  223. // SAFETY: We won't change the thread pointer in the current CPU when
  224. // we return here after some preemption.
  225. let current = CURRENT_THREAD.get().expect("Current thread is not set");
  226. // SAFETY: We can only use the returned value when we are in the context of the thread.
  227. unsafe { BorrowedArc::from_raw(current) }
  228. }
  229. pub fn raise(&self, signal: Signal) -> RaiseResult {
  230. self.signal_list.raise(signal)
  231. }
  232. /// # Safety
  233. /// This function is unsafe because it accesses the `current_cpu()`, which needs
  234. /// to be called in a preemption disabled context.
  235. pub unsafe fn load_thread_area32(&self) {
  236. if let Some(tls) = self.inner.lock().tls.as_ref() {
  237. CPU::local().as_mut().set_tls32(tls);
  238. }
  239. }
  240. pub fn set_user_tls(&self, tls: UserTLS) -> KResult<()> {
  241. self.inner.lock().tls = Some(tls);
  242. Ok(())
  243. }
  244. pub fn set_name(&self, name: Arc<[u8]>) {
  245. self.inner.lock().name = name;
  246. }
  247. pub fn get_name(&self) -> Arc<[u8]> {
  248. self.inner.lock().name.clone()
  249. }
  250. pub fn clear_child_tid(&self, clear_child_tid: Option<usize>) {
  251. self.inner.lock().clear_child_tid = clear_child_tid;
  252. }
  253. pub fn get_set_ctid(&self) -> Option<usize> {
  254. self.inner.lock().set_child_tid
  255. }
  256. pub fn get_clear_ctid(&self) -> Option<usize> {
  257. self.inner.lock().clear_child_tid
  258. }
  259. pub fn handle_syscall(&self, no: usize, args: [usize; 6]) -> Option<usize> {
  260. match syscall_handlers().get(no) {
  261. Some(Some(SyscallHandler {
  262. handler,
  263. name: _name,
  264. ..
  265. })) => handler(self, args),
  266. _ => {
  267. println_warn!("Syscall {no}({no:#x}) isn't implemented.");
  268. self.raise(Signal::SIGSYS);
  269. None
  270. }
  271. }
  272. }
  273. pub async fn force_kill(&self, signal: Signal) {
  274. let mut proc_list = ProcessList::get().write().await;
  275. unsafe {
  276. // SAFETY: Preemption is disabled.
  277. proc_list
  278. .do_exit(self, WaitType::Signaled(signal), false)
  279. .await;
  280. }
  281. }
  282. pub fn is_dead(&self) -> bool {
  283. self.dead.load(Ordering::SeqCst)
  284. }
  285. async fn real_run(&self) {
  286. if let Some(set_ctid) = self.get_set_ctid() {
  287. UserPointerMut::new(set_ctid as *mut u32)
  288. .expect("set_child_tid pointer is invalid")
  289. .write(self.tid)
  290. .expect("set_child_tid write failed");
  291. }
  292. while !self.is_dead() {
  293. if self.signal_list.has_pending_signal() {
  294. self.signal_list
  295. .handle(&mut self.trap_ctx.borrow(), &mut self.fpu_state.borrow())
  296. .await;
  297. }
  298. if self.is_dead() {
  299. return;
  300. }
  301. self.fpu_state.borrow().restore();
  302. unsafe {
  303. // SAFETY: We are returning to the context of the user thread.
  304. self.trap_ctx.borrow().trap_return();
  305. }
  306. self.fpu_state.borrow().save();
  307. let trap_type = self.trap_ctx.borrow().trap_type();
  308. match trap_type {
  309. TrapType::Fault(Fault::PageFault {
  310. error_code,
  311. address: addr,
  312. }) => {
  313. let mms = &self.process.mm_list;
  314. if let Err(signal) = mms.handle_user_page_fault(addr, error_code).await {
  315. self.signal_list.raise(signal);
  316. }
  317. }
  318. TrapType::Fault(Fault::BadAccess) => {
  319. self.signal_list.raise(Signal::SIGSEGV);
  320. }
  321. TrapType::Fault(Fault::InvalidOp) => {
  322. self.signal_list.raise(Signal::SIGILL);
  323. }
  324. TrapType::Fault(Fault::Unknown(_)) => unimplemented!("Unhandled fault"),
  325. TrapType::Irq(irqno) => default_irq_handler(irqno),
  326. TrapType::Timer => {
  327. timer_interrupt();
  328. yield_now().await;
  329. }
  330. TrapType::Syscall { no, args } => {
  331. if let Some(retval) = self.handle_syscall(no, args) {
  332. let mut trap_ctx = self.trap_ctx.borrow();
  333. trap_ctx.set_user_return_value(retval);
  334. #[cfg(target_arch = "riscv64")]
  335. {
  336. let pc = trap_ctx.get_program_counter();
  337. trap_ctx.set_program_counter(pc + 4);
  338. }
  339. }
  340. }
  341. }
  342. }
  343. }
  344. pub async fn run(self: Arc<Thread>) {
  345. struct ContextedRun<'a, F: Future>(F, &'a Thread);
  346. impl<F: Future> Future for ContextedRun<'_, F> {
  347. type Output = F::Output;
  348. fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
  349. let irq_state = disable_irqs_save();
  350. let (future, _) = unsafe {
  351. // SAFETY: We construct a pinned future and `&Thread` is `Unpin`.
  352. let me = self.as_mut().get_unchecked_mut();
  353. (Pin::new_unchecked(&mut me.0), me.1)
  354. };
  355. let retval = future.poll(ctx);
  356. irq_state.restore();
  357. retval
  358. }
  359. }
  360. ContextedRun(self.real_run(), &self).await
  361. }
  362. }
  363. async fn yield_now() {
  364. struct Yield {
  365. yielded: bool,
  366. }
  367. impl Future for Yield {
  368. type Output = ();
  369. fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  370. if self.as_mut().yielded {
  371. Poll::Ready(())
  372. } else {
  373. self.as_mut().yielded = true;
  374. cx.waker().wake_by_ref();
  375. Poll::Pending
  376. }
  377. }
  378. }
  379. Yield { yielded: false }.await;
  380. }
  381. pub fn new_thread_runnable(
  382. thread: Arc<Thread>,
  383. ) -> ThreadRunnable<impl Future<Output = impl Send + 'static> + Send + 'static> {
  384. ThreadRunnable {
  385. thread: thread.clone(),
  386. future: thread.run(),
  387. }
  388. }
  389. impl<F: Future> Contexted for ThreadRunnable<F> {
  390. fn load_running_context(&self) {
  391. self.thread.process.mm_list.activate();
  392. let raw_ptr: *const Thread = &raw const *self.thread;
  393. CURRENT_THREAD.set(NonNull::new(raw_ptr as *mut _));
  394. unsafe {
  395. // SAFETY: Preemption is disabled.
  396. self.thread.load_thread_area32();
  397. }
  398. unsafe {
  399. let trap_ctx_ptr: *const TrapContext = &raw const *self.thread.trap_ctx.borrow();
  400. // SAFETY:
  401. CPU::local()
  402. .as_mut()
  403. .load_interrupt_stack(trap_ctx_ptr as u64);
  404. }
  405. }
  406. fn restore_running_context(&self) {
  407. self.thread.process.mm_list.deactivate();
  408. CURRENT_THREAD.set(None);
  409. }
  410. }
  411. impl<F: Future> Run for ThreadRunnable<F> {
  412. type Output = F::Output;
  413. fn run(mut self: Pin<&mut Self>, waker: &Waker) -> RunState<Self::Output> {
  414. let mut ctx = Context::from_waker(waker);
  415. match unsafe {
  416. self.as_mut()
  417. .map_unchecked_mut(|me| &mut me.future)
  418. .poll(&mut ctx)
  419. } {
  420. Poll::Ready(output) => RunState::Finished(output),
  421. Poll::Pending => RunState::Running,
  422. }
  423. }
  424. }