use intrusive_collections::{RBTree, SinglyLinkedList};
use adapter::*;
use super::{ContTimePair, IdleOnDrop, PlanState, Scheduler};
use crate::{
config::Config,
continuation::{Adapter, Continuation, token},
fsm::Brand,
ptr::Irc,
simulator::{Mark, Prec},
};
use core::{cell::Cell, cmp::Reverse, fmt, ops::Range};
mod adapter;
pub struct Calendar<C: ?Sized + Config> {
time_layer: RBTree<TimeKey<C>>,
rank_layer: RBTree<RankKey<C>>,
mark: Range<Mark>,
counter: u64,
}
impl<C: ?Sized + Config> fmt::Debug for Calendar<C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug = f.debug_struct("Calendar");
debug
.field("time_layer", &self.time_layer)
.field("rank_layer", &self.rank_layer)
.finish()
}
}
unsafe impl<C> Scheduler for Calendar<C>
where
C: ?Sized + Config<Plan = Self>,
{
type Config = C;
type State = State<C>;
fn new(_: &C) -> Self {
Self {
time_layer: RBTree::new(TimeKey(Adapter::NEW)),
rank_layer: RBTree::new(RankKey(Adapter::NEW)),
mark: 1..1,
counter: 0,
}
}
fn update_rank<'brand>(&mut self, mark: Mark, rank: &Cell<C::Rank>, new_rank: C::Rank) {
use intrusive_collections::Bound::Included;
if self.mark.contains(&mark) {
let mut list = SinglyLinkedList::new(Adapter::NEW);
let mut cur = self.rank_layer.lower_bound_mut(Included(&(
Reverse(rank.get()),
mark,
Prec::new(),
0,
)));
while let Some(cont) = cur.get() {
if cont.brand(|inner, once| {
let next = unsafe { inner.token(once).into_next().unwrap_unchecked() };
inner.mark(&next).get() != mark
}) {
break;
}
list.push_front(unsafe { cur.remove().unwrap_unchecked() });
}
rank.set(new_rank);
for cont in list {
self.rank_layer.insert(cont);
}
}
}
fn schedule<'brand>(
&mut self,
cont: Irc<Continuation<'brand, C>>,
idle: token::Idle<'brand>,
time: C::Time,
) -> token::Next<'brand> {
let state = State {
count: self.counter,
time,
};
self.counter += 1;
let next: token::Next<'_> = cont.state().transition(idle, state);
self.time_layer.insert(IdleOnDrop::new(cont, &next));
next
}
fn defer<'brand>(
&mut self,
cont: Irc<Continuation<'brand, C>>,
busy: token::Busy<'brand>,
now: C::Time,
) -> token::Next<'brand> {
let idle: token::Idle<'_> = cont.state().transition(busy, ());
self.schedule(cont, idle, now)
}
fn activate<'brand>(
&mut self,
cont: Irc<Continuation<'brand, C>>,
idle: token::Idle<'brand>,
now: C::Time,
) -> token::Next<'brand> {
let state = State {
count: self.counter,
time: now,
};
self.counter += 1;
if !self.mark.contains(&cont.mark(&idle).get()) {
cont.mark(&idle).set(self.mark.end);
self.mark.end += 1;
}
let next: token::Next<'_> = cont.state().transition(idle, state);
self.rank_layer.insert(IdleOnDrop::new(cont, &next));
next
}
fn remove<'brand>(
&mut self,
cont: &Continuation<'brand, C>,
next: token::Next<'brand>,
_now: C::Time,
) -> token::Idle<'brand> {
cont.next_state(&next, |state| {
let share = cont.branded_share(&next);
if let Some(result) = self
.rank_layer
.find_mut(&(
Reverse(share.rank()),
share.mark().get(),
cont.prec(),
state.count,
))
.remove()
{
return result;
}
unsafe {
self.time_layer
.cursor_mut_from_ptr(cont.detach())
.remove()
.unwrap_unchecked()
}
})
.into_inner();
cont.state().transition(next, ())
}
fn extract(&mut self) -> Option<ContTimePair<C>> {
self.rank_layer
.front_mut()
.remove()
.or_else(|| {
self.mark.start = self.mark.end;
let mut cursor = self.time_layer.front_mut();
let mut first = cursor.remove()?;
let (now, mut r1, mut s1) = first.brand(|inner, next| {
inner.next_state(next, |state| {
let share = inner.branded_share(next);
let rank = share.rank();
let mark = share.mark();
mark.set(self.mark.end);
self.mark.end += 1;
(state.time, rank, state.count)
})
});
loop {
let Some(next) = cursor.get() else {
break;
};
if next.time().unwrap() != now {
break;
}
let next = cursor.remove().unwrap();
let (r2, s2) = next.brand(|inner, next| {
inner.next_state(next, |state| {
let share = inner.branded_share(next);
let rank = share.rank();
let mark = share.mark();
if !self.mark.contains(&mark.get()) {
mark.set(self.mark.end);
self.mark.end += 1;
}
(rank, state.count)
})
});
self.rank_layer.insert({
if (Reverse(r1), first.prec(), s1) > (Reverse(r2), next.prec(), s2) {
let tmp = first;
(first, r1, s1) = (next, r2, s2);
tmp
} else {
next
}
});
}
Some(first)
})
.map(|cont| ContTimePair {
time: cont.brand(|inner, next| inner.next_state(next, |s| s.time)),
cont: cont.into_inner(),
})
}
}
pub struct State<C: ?Sized + Config> {
time: C::Time,
count: u64,
}
impl<C: ?Sized + Config> fmt::Debug for State<C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("State")
.field("time", &self.time)
.field("count", &self.count)
.finish()
}
}
impl<C: ?Sized + Config> PlanState for State<C> {
type Time = C::Time;
fn time(&self) -> C::Time {
self.time
}
}