use super::*;
use crate::{
runtime::{
lock::PreemptScope,
sync::{
PiMutexClaimOutcome, PiMutexLockResult, PiMutexRef, PiWaitCancelOutcome,
PiWaitStateError,
},
},
thread::{
PiMutexWaiters, lock_pi_mutex_waiters, lock_raw_pi_mutex_waiters,
try_lock_raw_pi_mutex_waiters,
},
};
#[derive(Clone, Copy)]
struct PiRqFollowup {
reschedule: Option<RescheduleKind>,
owner_work: bool,
}
struct PiWaiterRefresh {
owner: Option<ThreadId>,
owner_next_lock: Option<PiMutexRaw>,
changed: bool,
ownerless_wake: Option<PiHandoffWake>,
}
struct PiHandoffWake {
core: Arc<ThreadCore>,
generation: u64,
rt_lock_wait: bool,
}
impl PiHandoffWake {
fn new(core: Arc<ThreadCore>, generation: u64) -> Self {
let rt_lock_wait = core.in_rt_lock_wait();
Self {
core,
generation,
rt_lock_wait,
}
}
fn deliver(self, system: &TaskSystem) {
if self.rt_lock_wait {
system.wake_rt_lock_thread(&self.core, self.generation);
} else {
system.wake_thread_from_current_cpu(&self.core, crate::thread::WakeIntent::Normal);
}
}
}
impl TaskSystem {
fn pi_thread_core(&self, thread: ThreadId) -> Result<Arc<ThreadCore>, TaskError> {
let state = self.state.lock();
Ok(Arc::clone(&state.thread_record(thread)?.core))
}
fn pi_donation(&self, core: &Arc<ThreadCore>) -> Result<PiDonation, TaskError> {
let (policy, root) = {
let sched = core.sched().lock();
(
core.effective_policy_snapshot(),
sched.pi.donor.unwrap_or(core.id()),
)
};
self.pi_donation_from_snapshot(core, policy, root)
}
fn pi_donation_from_snapshot(
&self,
core: &Arc<ThreadCore>,
policy: SchedulePolicy,
root: ThreadId,
) -> Result<PiDonation, TaskError> {
let root_core = if root == core.id() {
Arc::clone(core)
} else {
self.pi_thread_core(root)?
};
Ok(PiDonation::new(
policy,
root,
core.effective_scheduling_urgency(),
core,
&root_core,
))
}
}
mod graph;
mod operations;
mod schedule;
mod transition;
use transition::{
PiOwnerRqAccountingPath, owner_rq_needs_current_settlement, publish_owner_after_waiter_detach,
};
#[cfg(axtest)]
mod axtest;
#[cfg(axtest)]
pub use {
axtest::PiScheduleTestProbeSnapshot, axtest::begin_pi_schedule_test_probe,
axtest::end_pi_schedule_test_probe, axtest::pi_schedule_test_probe_snapshot,
};