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