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}