ax_task/sched/system/task_system/
model.rs1use super::*;
4
5#[derive(Debug, thiserror::Error)]
10#[error("{error}")]
11pub struct OwnedThreadReapError {
12 error: TaskError,
13 handle: ThreadHandle,
14}
15
16impl OwnedThreadReapError {
17 pub(super) const fn new(error: TaskError, handle: ThreadHandle) -> Self {
18 Self { error, handle }
19 }
20
21 pub const fn task_error(&self) -> TaskError {
23 self.error
24 }
25
26 pub fn into_retry_handle(self) -> ThreadHandle {
28 self.handle
29 }
30}
31
32#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
34pub struct DeferredTaskWorkBatch {
35 pub(super) deadline_events: usize,
36 pub(super) deadline_callbacks: usize,
37 pub(super) scheduler_tick_events: usize,
38 pub(super) scheduler_tick_callbacks: usize,
39 pub(super) exit_callbacks: usize,
40 pub(super) reaped_threads: usize,
41 pub(super) coroutine_reclaims: usize,
42 pub(super) address_space_reclaims: usize,
43}
44
45impl DeferredTaskWorkBatch {
46 pub const fn processed(self) -> usize {
48 self.deadline_events
49 + self.scheduler_tick_events
50 + self.exit_callbacks
51 + self.reaped_threads
52 + self.coroutine_reclaims
53 + self.address_space_reclaims
54 }
55
56 pub const fn deadline_callbacks(self) -> usize {
58 self.deadline_callbacks
59 }
60
61 pub const fn scheduler_tick_callbacks(self) -> usize {
63 self.scheduler_tick_callbacks
64 }
65
66 pub const fn coroutine_reclaims(self) -> usize {
68 self.coroutine_reclaims
69 }
70
71 pub const fn address_space_reclaims(self) -> usize {
73 self.address_space_reclaims
74 }
75
76 pub const fn made_progress(self) -> bool {
78 self.processed() != 0
79 }
80
81 pub const fn saturated(self, limit: usize) -> bool {
83 let capped_limit = if limit < crate::runtime::config::DEFAULT_BATCH_LIMIT {
84 limit
85 } else {
86 crate::runtime::config::DEFAULT_BATCH_LIMIT
87 };
88 capped_limit != 0 && self.processed() == capped_limit
89 }
90}
91
92#[derive(Debug)]
105pub struct TaskSystem {
106 pub(super) config: TaskSystemConfig,
107 pub(super) cpu_remotes: Vec<Arc<CpuRemote>>,
108 pub(super) state: PreemptTicketLock<TaskSystemState>,
111 pub(super) root_domain: RootDomain,
112 pub(super) deferred_coroutine_reclaims: SchedulerInbox,
113 pub(super) deferred_deadline_callbacks: SchedulerInbox,
114 pub(super) deferred_scheduler_ticks: SchedulerInbox,
115 pub(super) task_work: Arc<TaskWorkDoorbell>,
116}
117
118#[derive(Clone, Copy, Debug, Eq, PartialEq)]
119pub(super) enum BalanceReason {
120 RtDeadlinePush,
121 IdlePull,
122 FairPeriodic,
123}
124
125#[derive(Clone, Copy, Debug, Eq, PartialEq)]
131pub(super) enum BalanceTransferOutcome {
132 Migrated(ThreadId),
133 NoCandidate,
134 Retry,
135}
136
137impl BalanceTransferOutcome {
138 pub(super) const fn migrated(self) -> Option<ThreadId> {
139 match self {
140 Self::Migrated(thread) => Some(thread),
141 Self::NoCandidate | Self::Retry => None,
142 }
143 }
144}
145
146#[derive(Clone, Copy, Debug, Eq, PartialEq)]
147pub(super) enum FairBalanceResult {
148 Migrated(ThreadId),
149 Balanced,
150 Constrained,
151}
152
153impl FairBalanceResult {
154 pub(super) const fn migrated(self) -> Option<ThreadId> {
155 match self {
156 Self::Migrated(thread) => Some(thread),
157 Self::Balanced | Self::Constrained => None,
158 }
159 }
160}
161
162pub(super) const FAIR_BALANCE_BALANCED_BACKOFF_FACTOR: u64 = 2;
163pub(super) const FAIR_BALANCE_CONSTRAINED_BACKOFF_FACTOR: u64 = 64;
164
165#[derive(Clone, Copy, Debug, Eq, PartialEq)]
166pub(super) enum DeferredTaskWorkClass {
167 Deadline,
168 SchedulerTick,
169 Exit,
170 Reap,
171 Reclaim,
172}
173
174impl DeferredTaskWorkClass {
175 pub(super) const COUNT: usize = 5;
176
177 pub(super) const fn next(self) -> Self {
178 match self {
179 Self::Deadline => Self::SchedulerTick,
180 Self::SchedulerTick => Self::Exit,
181 Self::Exit => Self::Reap,
182 Self::Reap => Self::Reclaim,
183 Self::Reclaim => Self::Deadline,
184 }
185 }
186}
187
188pub(super) struct DetachedOwnerMessageBatch<'batch> {
194 pub(super) messages: &'batch [InboxMessage],
195 pub(super) next: usize,
196}
197
198impl<'batch> DetachedOwnerMessageBatch<'batch> {
199 pub(super) const fn new(messages: &'batch [InboxMessage]) -> Self {
200 Self { messages, next: 0 }
201 }
202
203 pub(super) fn next(&mut self) -> Option<InboxMessage> {
204 let message = self.messages.get(self.next).copied()?;
205 self.next += 1;
206 Some(message)
207 }
208
209 pub(super) fn release(message: InboxMessage) {
210 if message.payload() == 0 {
211 return;
212 }
213 let core = unsafe {
214 Arc::from_raw(ptr::with_exposed_provenance::<ThreadCore>(
218 message.payload(),
219 ))
220 };
221 let _delivery = core.accept_scheduler_inbox_delivery();
222 }
223}
224
225impl Drop for DetachedOwnerMessageBatch<'_> {
226 fn drop(&mut self) {
227 for &message in &self.messages[self.next..] {
228 Self::release(message);
229 }
230 }
231}
232
233#[derive(Clone, Copy, Debug, Eq, PartialEq)]
234pub(super) struct FairPolicyPlacement {
235 pub(super) source_virtual_time: u64,
236 pub(super) destination_virtual_time: u64,
237}