monitor/mon/compartment/
compthread.rs1use dynlink::{compartment::MONITOR_COMPARTMENT_ID, context::Context};
2use miette::IntoDiagnostic;
3use twizzler_abi::{
4 object::MAX_SIZE,
5 upcall::{ResumeFlags, UpcallFrame},
6};
7use twizzler_rt_abi::object::ObjID;
8
9use crate::mon::{
10 space::MapHandle,
11 thread::{ManagedThread, ThreadMgr, DEFAULT_STACK_SIZE, STACK_SIZE_MIN_ALIGN},
12};
13
14#[allow(dead_code)]
15pub(super) struct CompThread {
16 pub(crate) stack_object: StackObject,
17 pub(crate) thread: ManagedThread,
18}
19
20impl CompThread {
21 #[allow(clippy::too_many_arguments)]
24 pub fn new(
25 tmgr: &mut ThreadMgr,
26 dynlink: &mut Context,
27 stack: StackObject,
28 instance: ObjID,
29 main_thread_comp: Option<ObjID>,
30 entry: usize,
31 arg: usize,
32 suspend_on_start: bool,
33 ) -> miette::Result<Self> {
34 let frame = stack.get_entry_frame(instance, entry, arg);
35 let start = move || {
36 twizzler_abi::syscall::sys_sctx_attach(instance).unwrap();
37 let flags = if suspend_on_start {
38 ResumeFlags::SUSPEND
39 } else {
40 ResumeFlags::empty()
41 };
42 unsafe { twizzler_abi::syscall::sys_thread_resume_from_upcall(&frame, flags) };
43 };
44 let mon = dynlink.get_compartment_mut(MONITOR_COMPARTMENT_ID).unwrap();
45 let mt = tmgr
46 .start_thread(mon, Box::new(start), main_thread_comp)
47 .into_diagnostic()?;
48 Ok(Self {
49 stack_object: stack,
50 thread: mt,
51 })
52 }
53}
54
55pub(crate) struct StackObject {
56 handle: MapHandle,
57 stack_size: usize,
58}
59
60impl StackObject {
61 pub fn new(handle: MapHandle, stack_size: usize) -> miette::Result<Self> {
63 let stack_size = stack_size
65 .clamp(DEFAULT_STACK_SIZE, MAX_SIZE / 2)
66 .next_multiple_of(STACK_SIZE_MIN_ALIGN);
67
68 Ok(Self { handle, stack_size })
69 }
70
71 pub fn stack_comp_start(&self) -> usize {
73 self.handle.addrs().start
74 }
75
76 pub fn stack_size(&self) -> usize {
78 self.stack_size
79 }
80
81 #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
84 pub fn initial_stack_ptr(&self) -> usize {
86 self.stack_comp_start() + self.stack_size
87 }
88
89 pub fn get_entry_frame(&self, ctx: ObjID, entry: usize, arg: usize) -> UpcallFrame {
91 UpcallFrame::new_entry_frame(
92 self.initial_stack_ptr(),
93 self.stack_size(),
94 0,
95 ctx,
96 entry,
97 arg,
98 )
99 }
100}