ax_task/sched/system/task_system/park_exit/
park.rs1use super::*;
4
5impl TaskSystem {
6 pub fn prepare_park(
8 &self,
9 cpu: Pin<&mut CpuLocal>,
10 current: &ThreadHandle,
11 ) -> Result<ParkPrepare, TaskError> {
12 self.ensure_owner_cpu_context(&cpu)?;
13 self.ensure_owner_cpu_online(&cpu)?;
14 let core = current.runtime_core_arc();
15 let placement = core.sched().placement();
16 if placement.queued_cpu() != Some(cpu.owner()) || placement.on_cpu() != Some(cpu.owner()) {
17 return Err(TaskError::StaleThreadId);
18 }
19 self.prepare_current_park(core)
20 }
21
22 pub(crate) fn prepare_current_park(
29 &self,
30 current: &ThreadCore,
31 ) -> Result<ParkPrepare, TaskError> {
32 let core = current;
33 let placement = core.sched().placement();
34 let queued_cpu = placement.queued_cpu();
35 if core.state() != ThreadState::Running
36 || queued_cpu.is_none()
37 || placement.on_cpu() != queued_cpu
38 {
39 return Err(TaskError::StaleThreadId);
40 }
41 if core.take_park_notification() {
42 return Ok(ParkPrepare::Notified);
43 }
44 let generation = core.next_park_generation()?;
45 core.transition_state(ThreadState::Parking)?;
46 Ok(ParkPrepare::Prepared(ParkTicket::new(
47 core.id(),
48 generation,
49 )))
50 }
51
52 pub fn cancel_park(
54 &self,
55 cpu: Pin<&mut CpuLocal>,
56 current: &ThreadHandle,
57 token: &mut ParkTicket,
58 ) -> Result<(), TaskError> {
59 self.cancel_current_park(cpu, current.runtime_core_arc(), token)
60 }
61
62 pub(crate) fn cancel_current_park(
63 &self,
64 cpu: Pin<&mut CpuLocal>,
65 current: &ThreadCore,
66 token: &mut ParkTicket,
67 ) -> Result<(), TaskError> {
68 self.ensure_owner_cpu_context(&cpu)?;
69 if token.is_resolved() || current.id() != token.thread() {
70 return Err(TaskError::StaleThreadId);
71 }
72 self.ensure_owner_cpu_online(&cpu)?;
73 let core = current;
74 if core.park_generation() != token.generation() {
75 return Err(TaskError::StaleThreadId);
76 }
77 let placement = core.sched().placement();
78 if core.state() != ThreadState::Parking
79 || placement.queued_cpu() != Some(cpu.owner())
80 || placement.on_cpu() != Some(cpu.owner())
81 {
82 return Err(TaskError::StaleThreadId);
83 }
84 core.transition_state(ThreadState::Running)?;
85 cpu.finish_park_preemption(true);
86 token.mark_resolved();
87 Ok(())
88 }
89}