ax_runtime/thread/
spawn.rs1use ax_task::thread::{PreparedThread, ThreadBuilder};
4
5use super::*;
6
7pub fn builder(name: String) -> ThreadBuilder {
9 ThreadBuilder::new(name)
10 .stack_size(default_task_stack_size())
11 .guard_size(if cfg!(feature = "stack-guard-page") {
12 PAGE_SIZE
13 } else {
14 0
15 })
16}
17
18pub struct UserContextOptions {
20 pub(super) address_space: TaskAddressSpace,
21 #[cfg(all(target_arch = "riscv64", feature = "fp-simd"))]
22 pub(super) fp_state: Option<ax_hal::cpu::registers::FpState>,
23 #[cfg(all(not(target_arch = "riscv64"), feature = "fp-simd", feature = "uspace"))]
24 pub(super) inherit_current_fp: bool,
25}
26impl UserContextOptions {
27 pub fn new(address_space: TaskAddressSpace) -> Self {
29 Self {
30 address_space,
31 #[cfg(all(target_arch = "riscv64", feature = "fp-simd"))]
32 fp_state: None,
33 #[cfg(all(not(target_arch = "riscv64"), feature = "fp-simd", feature = "uspace"))]
34 inherit_current_fp: false,
35 }
36 }
37 #[cfg(all(target_arch = "riscv64", feature = "fp-simd"))]
39 pub fn with_fp_state(mut self, state: ax_hal::cpu::registers::FpState) -> Self {
40 self.fp_state = Some(state);
41 self
42 }
43 #[cfg(all(not(target_arch = "riscv64"), feature = "fp-simd", feature = "uspace"))]
45 pub fn inherit_current_fp(mut self) -> Self {
46 self.inherit_current_fp = true;
47 self
48 }
49}
50
51pub unsafe fn prepare_user_thread(
57 builder: ThreadBuilder,
58 entry: impl FnOnce() + Send + 'static,
59 options: UserContextOptions,
60) -> Result<PreparedThread, TaskError> {
61 #[cfg(all(not(target_arch = "riscv64"), feature = "fp-simd", feature = "uspace"))]
62 if options.inherit_current_fp {
63 context::validate_current_user_fp_clone_context()?;
64 }
65 unsafe {
68 builder.prepare_with(entry, |request, trampoline| {
69 create_user_resources(request, trampoline, options)
70 })
71 }
72}
73
74pub fn exit_current(code: i32) -> ! {
76 if primary_bootstrap_thread() == current_thread_id().ok() {
77 crate::terminate();
78 }
79 ax_task::thread::current::exit_current(code)
80}