awkernel_sync 0.1.1

no_std synchronization primitives (mutex, rwlock, spinlock, MCS lock) with interrupt guards for the Awkernel operating system.
docs.rs failed to build awkernel_sync-0.1.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

awkernel_sync

Synchronization primitives for the Awkernel operating system.

awkernel_sync is a no_std crate providing locks and interrupt guards that work both inside a kernel (bare metal) and in a hosted std environment for testing. Each locking primitive automatically disables interrupts while the lock is held, via an InterruptGuard, so it is safe to use from interrupt context.

Primitives

Type Description
mutex::Mutex Mutual-exclusion lock. Backed by an MCS lock (no_std), a spin lock (spinlock feature), or parking_lot::Mutex (std feature).
mcs::MCSLock MCS queue lock; fair and cache-friendly under contention. Requires a per-caller MCSNode.
spinlock::SpinLock Simple test-and-set spin lock.
rwlock::RwLock Reader-writer lock.
InterruptGuard RAII guard that disables interrupts on creation and restores the previous state on drop.

Features

You must enable exactly one architecture feature. If none is enabled the crate fails to compile with an explanatory compile_error!.

Feature Description
x86 x86-64 bare-metal interrupt control (pulls in the x86_64 crate).
x86_mwait Use monitor/mwait for spin-wait backoff on x86-64.
aarch64 AArch64 bare-metal interrupt control.
rv64 RISC-V (64-bit) bare-metal interrupt control.
rv32 RISC-V (32-bit) bare-metal interrupt control.
std Hosted build for tests/tooling; uses parking_lot and no-op interrupt guards.
spinlock Make mutex::Mutex use a spin lock instead of the MCS lock (no_std only).

There is no default feature.

Usage

Add the crate with the architecture feature that matches your target:

[dependencies]
awkernel_sync = { version = "0.1", features = ["x86"] }

Mutex

Mutex::lock takes a caller-provided MCSNode, which lives on the caller's stack and avoids heap allocation in the queue lock:

use awkernel_sync::mutex::{MCSNode, Mutex};

let m = Mutex::new(0);

let mut node = MCSNode::new();
let mut guard = m.lock(&mut node);
*guard += 1;

RwLock

use awkernel_sync::rwlock::RwLock;

let lock = RwLock::new(5);

{
    let r = lock.read();
    assert_eq!(*r, 5);
}

{
    let mut w = lock.write();
    *w += 1;
}

InterruptGuard

use awkernel_sync::InterruptGuard;

{
    let _guard = InterruptGuard::new();
    // Interrupts are disabled in this scope.
}
// The previous interrupt state is restored here.

Testing

MCSLock and RwLock are model-checked with loom. The checks live in tests/ and are gated behind the loom cfg:

RUSTFLAGS="--cfg loom" cargo test --features std

License

Licensed under either of

at your option.