thread.rs 14 KB

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