dope-core 0.35.1

Owned native I/O and completion driver for dope
Documentation
use std::cell;

use o3::mem::quota;

use crate::{
    driver,
    driver::{
        schedule,
        schedule::{clock::timer, ready},
    },
};

pub(crate) mod lanes;
pub mod scope;

pub(super) enum ReactorLane {}
pub(super) enum CoordLane {}
pub(super) enum AppLane {}
pub(super) enum MaintLane {}

#[derive(Clone, Copy)]
pub(super) enum Cursor {
    First,
    Second,
}

impl Cursor {
    const fn next(self) -> Self {
        match self {
            Self::First => Self::Second,
            Self::Second => Self::First,
        }
    }

    const fn index(self) -> usize {
        match self {
            Self::First => 0,
            Self::Second => 1,
        }
    }
}

pub(super) struct Reactor {
    pub(super) ledger: quota::Ledger<ReactorLane>,
    pub(super) cursor: cell::Cell<Cursor>,
}

pub(super) struct Lanes {
    pub(super) ready: quota::Ledger<ready::Lane>,
    pub(super) coord: quota::Ledger<CoordLane>,
    pub(super) app: quota::Ledger<AppLane>,
    pub(super) timers: quota::Ledger<timer::Tag>,
    pub(super) maint: quota::Ledger<MaintLane>,
}

pub(in crate::driver) struct Core<'d> {
    pub(super) driver: driver::Reference<'d>,
    pub(super) reactor: Reactor,
    pub(super) lanes: Lanes,
    pub(super) deferred: cell::Cell<bool>,
}

impl<'d> Core<'d> {
    pub(in crate::driver) fn new(driver: driver::Reference<'d>) -> Self {
        Self {
            driver,
            reactor: Reactor {
                ledger: quota::Ledger::new(schedule::LIMIT),
                cursor: cell::Cell::new(Cursor::First),
            },
            lanes: Lanes {
                ready: quota::Ledger::new(schedule::LIMIT),
                coord: quota::Ledger::new(schedule::LIMIT),
                app: quota::Ledger::new(schedule::LIMIT),
                timers: quota::Ledger::new(schedule::LIMIT),
                maint: quota::Ledger::new(schedule::LIMIT),
            },
            deferred: cell::Cell::new(false),
        }
    }

    pub(super) fn reset(&mut self) {
        self.deferred.set(false);
        self.reactor.ledger.reset(schedule::LIMIT);
        self.lanes.ready.reset(schedule::LIMIT);
        self.lanes.coord.reset(schedule::LIMIT);
        self.lanes.app.reset(schedule::LIMIT);
        self.lanes.timers.reset(schedule::LIMIT);
        self.lanes.maint.reset(schedule::LIMIT);
    }

    pub(super) fn is_exhausted(&self) -> bool {
        self.deferred.get()
            || self.reactor.ledger.remaining() == 0
            || self.lanes.ready.remaining() == 0
            || self.lanes.app.remaining() == 0
            || self.lanes.timers.remaining() == 0
            || self.lanes.maint.remaining() == 0
    }
}