ax-task 0.7.1

OS-independent IRQ-safe SMP task scheduling core
Documentation
use core::panic::Location;

use crate::sync::{
    lockdep as common,
    lockdep::{HeldLockSnapshot, LockSubclass, LockdepMapView, PreparedAcquire},
    mutex::RawMutex,
};

fn current_held_locks() -> HeldLockSnapshot {
    common::current_task_held_lock_snapshot()
}

pub(crate) struct LockdepAcquire {
    addr: usize,
    prepared: PreparedAcquire,
    inner: common::Lockdep,
}

pub(in crate::sync) struct LockdepAcquireRequest<'lock> {
    pub map: LockdepMapView<'lock>,
    pub addr: usize,
    pub subclass: LockSubclass,
    pub is_try: bool,
    pub caller: &'static Location<'static>,
}

impl LockdepAcquire {
    #[inline(always)]
    #[track_caller]
    pub(crate) fn prepare_nested(lock: &RawMutex, is_try: bool, subclass: LockSubclass) -> Self {
        let addr = lock as *const _ as *const () as usize;
        Self::prepare_view(LockdepAcquireRequest {
            map: lock.lockdep.view(),
            addr,
            subclass,
            is_try,
            caller: Location::caller(),
        })
    }

    pub(in crate::sync) fn prepare_view(request: LockdepAcquireRequest<'_>) -> Self {
        let prepared = common::prepare_acquire_with_snapshot_view_nested_with_sleep(
            request.map,
            "mutex",
            request.addr,
            request.caller,
            current_held_locks(),
            request.subclass,
            false,
        );
        let inner = common::Lockdep::prepare("mutex", request.addr, request.is_try, None);
        Self {
            addr: request.addr,
            prepared,
            inner,
        }
    }

    #[inline(always)]
    pub(crate) fn finish(self, acquired: bool) {
        self.inner.finish(acquired);
        if acquired {
            common::finish_acquire_task(self.prepared, self.addr);
        }
    }
}

#[inline(always)]
pub(crate) fn release(lock: &RawMutex) {
    let addr = lock as *const _ as *const () as usize;
    release_external(addr);
}

#[inline(always)]
pub(in crate::sync) fn release_external(addr: usize) {
    common::release_task(addr);
    common::Lockdep::release("mutex", addr, None);
}