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) cancellation_events: usize,
41 pub(super) reaped_threads: usize,
42 pub(super) execution_reclaims: usize,
43 pub(super) coroutine_reclaims: usize,
44 pub(super) address_space_reclaims: usize,
45}
46
47impl DeferredTaskWorkBatch {
48 pub const fn processed(self) -> usize {
50 self.deadline_events
51 + self.scheduler_tick_events
52 + self.exit_callbacks
53 + self.cancellation_events
54 + self.reaped_threads
55 + self.execution_reclaims
56 + self.coroutine_reclaims
57 + self.address_space_reclaims
58 }
59
60 pub const fn deadline_callbacks(self) -> usize {
62 self.deadline_callbacks
63 }
64
65 pub const fn cancellation_events(self) -> usize {
67 self.cancellation_events
68 }
69
70 pub const fn scheduler_tick_callbacks(self) -> usize {
72 self.scheduler_tick_callbacks
73 }
74
75 pub const fn coroutine_reclaims(self) -> usize {
77 self.coroutine_reclaims
78 }
79
80 pub const fn address_space_reclaims(self) -> usize {
82 self.address_space_reclaims
83 }
84
85 pub const fn made_progress(self) -> bool {
87 self.processed() != 0
88 }
89
90 pub const fn saturated(self, limit: usize) -> bool {
92 let capped_limit = if limit < crate::runtime::config::DEFAULT_BATCH_LIMIT {
93 limit
94 } else {
95 crate::runtime::config::DEFAULT_BATCH_LIMIT
96 };
97 capped_limit != 0 && self.processed() == capped_limit
98 }
99}
100
101#[derive(Debug)]
114pub struct TaskSystem {
115 pub(super) config: TaskSystemConfig,
116 pub(super) cpu_remotes: Vec<Arc<CpuRemote>>,
117 pub(super) state: PreemptTicketLock<TaskSystemState>,
120 pub(super) root_domain: RootDomain,
121 pub(super) deferred_coroutine_reclaims: SchedulerInbox,
122 pub(super) deferred_thread_cancellations: SchedulerInbox,
123 pub(super) deferred_deadline_callbacks: SchedulerInbox,
124 pub(super) deferred_scheduler_ticks: SchedulerInbox,
125 pub(super) task_work: Arc<TaskWorkDoorbell>,
126}
127
128#[derive(Clone, Copy, Debug, Eq, PartialEq)]
129pub(super) enum BalanceReason {
130 RtDeadlinePush,
131 IdlePull,
132 FairPeriodic,
133}
134
135#[derive(Clone, Copy, Debug, Eq, PartialEq)]
141pub(super) enum BalanceTransferOutcome {
142 Migrated(ThreadId),
143 NoCandidate,
144 Retry,
145}
146
147impl BalanceTransferOutcome {
148 pub(super) const fn migrated(self) -> Option<ThreadId> {
149 match self {
150 Self::Migrated(thread) => Some(thread),
151 Self::NoCandidate | Self::Retry => None,
152 }
153 }
154}
155
156#[derive(Clone, Copy, Debug, Eq, PartialEq)]
157pub(super) enum FairBalanceResult {
158 Migrated(ThreadId),
159 Balanced,
160 Constrained,
161}
162
163impl FairBalanceResult {
164 pub(super) const fn migrated(self) -> Option<ThreadId> {
165 match self {
166 Self::Migrated(thread) => Some(thread),
167 Self::Balanced | Self::Constrained => None,
168 }
169 }
170}
171
172pub(super) const FAIR_BALANCE_BALANCED_BACKOFF_FACTOR: u64 = 2;
173pub(super) const FAIR_BALANCE_CONSTRAINED_BACKOFF_FACTOR: u64 = 64;
174
175#[derive(Clone, Copy, Debug, Eq, PartialEq)]
176pub(super) enum DeferredTaskWorkClass {
177 Cancellation,
178 Deadline,
179 SchedulerTick,
180 Exit,
181 Reap,
182 Reclaim,
183}
184
185impl DeferredTaskWorkClass {
186 pub(super) const COUNT: usize = 6;
187
188 pub(super) const fn next(self) -> Self {
189 match self {
190 Self::Cancellation => Self::Deadline,
191 Self::Deadline => Self::SchedulerTick,
192 Self::SchedulerTick => Self::Exit,
193 Self::Exit => Self::Reap,
194 Self::Reap => Self::Reclaim,
195 Self::Reclaim => Self::Cancellation,
196 }
197 }
198}
199
200pub(super) struct DetachedOwnerMessageBatch<'batch> {
206 pub(super) messages: &'batch [InboxMessage],
207 pub(super) next: usize,
208}
209
210impl<'batch> DetachedOwnerMessageBatch<'batch> {
211 pub(super) const fn new(messages: &'batch [InboxMessage]) -> Self {
212 Self { messages, next: 0 }
213 }
214
215 pub(super) fn next(&mut self) -> Option<InboxMessage> {
216 let message = self.messages.get(self.next).copied()?;
217 self.next += 1;
218 Some(message)
219 }
220
221 pub(super) fn release(message: InboxMessage) {
222 if message.payload() == 0 {
223 return;
224 }
225 let core = unsafe {
226 Arc::from_raw(ptr::with_exposed_provenance::<ThreadCore>(
230 message.payload(),
231 ))
232 };
233 let _delivery = core.accept_scheduler_inbox_delivery();
234 }
235}
236
237impl Drop for DetachedOwnerMessageBatch<'_> {
238 fn drop(&mut self) {
239 for &message in &self.messages[self.next..] {
240 Self::release(message);
241 }
242 }
243}
244
245#[derive(Clone, Copy, Debug, Eq, PartialEq)]
246pub(super) struct FairPolicyPlacement {
247 pub(super) source_virtual_time: u64,
248 pub(super) destination_virtual_time: u64,
249}