Skip to main content

ax_task/thread/handle/
control.rs

1//! Thread control through one generation-valid management lease.
2
3use super::*;
4use crate::{
5    runtime::context::{runtime_task_system, validate_task_context},
6    sched::policy::SchedulePolicy,
7    thread::{
8        current::{current_thread_id, set_current_thread_affinity, validate_blocking_context},
9        error::TaskError,
10        spec::CpuSet,
11    },
12};
13
14impl ThreadHandle {
15    /// Updates a thread scheduling policy through its owner CPU.
16    ///
17    /// # Errors
18    ///
19    /// Returns [`TaskError::UnsafeContext`] in hard IRQ context and propagates
20    /// policy validation, Deadline admission, identity, and CPU publication
21    /// failures.
22    pub fn set_policy(&self, policy: SchedulePolicy) -> Result<(), TaskError> {
23        let thread = self.id();
24        validate_task_context()?;
25        runtime_task_system()?.set_thread_policy(thread, policy)
26    }
27
28    /// Returns a copy of a thread's CPU affinity.
29    pub fn affinity(&self) -> Result<CpuSet, TaskError> {
30        let thread = self.id();
31        runtime_task_system()?.thread_affinity(thread)
32    }
33
34    /// Requests an affinity change and returns its owner-runqueue completion.
35    ///
36    /// Dropping the completion leaves the request asynchronous. Use `wait()` or
37    /// [`Self::set_affinity_and_wait`] when placement must finish before return.
38    pub fn request_affinity(
39        &self,
40        affinity: CpuSet,
41    ) -> Result<crate::sched::ThreadAffinityChange, TaskError> {
42        let thread = self.id();
43        validate_task_context()?;
44        runtime_task_system()?.request_thread_affinity(thread, affinity)
45    }
46
47    /// Updates a remote thread's affinity and waits for owner-runqueue completion.
48    ///
49    /// A successful return guarantees that this update was ordered through the
50    /// target's owner runqueue. If no later setter superseded it, the target no
51    /// longer executes on, is queued on, or has an in-flight transfer to a CPU
52    /// excluded by this affinity. Setters that join the same outstanding owner
53    /// transition share the target's monotonically increasing completion sequence.
54    pub fn set_affinity_and_wait(&self, affinity: CpuSet) -> Result<(), TaskError> {
55        let thread = self.id();
56        if current_thread_id()? == thread {
57            return set_current_thread_affinity(affinity);
58        }
59        validate_blocking_context()?;
60        runtime_task_system()?
61            .request_thread_affinity(thread, affinity)?
62            .wait()
63    }
64
65    /// Looks up a generation-valid thread through the runtime-owned task system.
66    pub fn lookup(thread: ThreadId) -> Result<Self, TaskError> {
67        runtime_task_system()?.thread_handle(thread)
68    }
69
70    /// Returns a cumulative charged-runtime snapshot for a live thread.
71    pub fn runtime(&self) -> Result<ThreadRuntimeSnapshot, TaskError> {
72        let thread = self.id();
73        runtime_task_system()?.thread_runtime(thread)
74    }
75}