Skip to main content

ax_cpu/
task_local.rs

1use core::ptr::NonNull;
2
3use cpu_local::ExecutionContextHeader;
4
5use crate::KernelTlsBase;
6
7/// Architecture-neutral task state participating in the final switch tail.
8///
9/// Architecture switch tails consume the current-header pointer whenever the
10/// hardware provides a task register independent of kernel TLS. Backends whose
11/// task register is also the TLS base use the CPU runtime anchor for current.
12/// Keeping both values adjacent centralizes their switch-time ownership.
13#[repr(C)]
14#[derive(Debug, Default)]
15pub struct TaskLocalState {
16    pub(crate) context_header: usize,
17    pub(crate) kernel_tls: KernelTlsBase,
18}
19
20impl TaskLocalState {
21    /// Creates empty task-local switch state.
22    pub const fn new() -> Self {
23        Self {
24            context_header: 0,
25            kernel_tls: KernelTlsBase::new(0),
26        }
27    }
28
29    /// Configures the task-owned TLS base for the selected image mode.
30    pub(crate) fn set_kernel_tls(&mut self, kernel_tls: KernelTlsBase) {
31        self.kernel_tls = KernelTlsBase::for_task_context(kernel_tls);
32    }
33
34    /// Sets the stable task-owned execution-context header.
35    pub fn set_context_header(&mut self, header: NonNull<ExecutionContextHeader>) {
36        self.context_header = header.as_ptr() as usize;
37    }
38
39    /// Returns the configured task-owned execution-context header.
40    pub const fn context_header(&self) -> Option<NonNull<ExecutionContextHeader>> {
41        NonNull::new(self.context_header as *mut ExecutionContextHeader)
42    }
43}
44
45const _: () = {
46    assert!(core::mem::size_of::<TaskLocalState>() == 2 * core::mem::size_of::<usize>());
47    assert!(core::mem::align_of::<TaskLocalState>() == core::mem::align_of::<usize>());
48};