Skip to main content

ksync/
raw_lock.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use pin_init::PinInit;
6
7/// Trait defining a policy for how a lock should be acquired and released. A given `RawLock` may
8/// have multiple policy implementations allowing a specific instance of a lock to be acquired, at
9/// different times, in different ways.
10pub trait LockPolicy<L: RawLock + ?Sized> {
11    /// Arguments passed when acquiring the lock under this policy.
12    type AcquireArgs: Copy;
13
14    /// State returned from lock acquisition and subsequently passed to lock release.
15    type GuardState: Default + Copy;
16
17    /// Acquires the raw synchronization lock under a type-level lock class.
18    ///
19    /// # Safety
20    ///
21    /// 1. The `entry` pointer must point to a valid, exclusive, stack-allocated `LockEntry` slot
22    ///    which will be registered in the thread's active list.
23    /// 2. The caller must ensure that the `entry` memory remains pinned on the stack and is not
24    ///    dropped or moved until the matching `release` call completes.
25    unsafe fn acquire(
26        lock: &L,
27        entry: *mut L::LockEntry,
28        args: Self::AcquireArgs,
29    ) -> Self::GuardState;
30
31    /// Re-acquires the raw synchronization lock using existing guard state (e.g. after
32    /// `call_unlocked`).
33    ///
34    /// # Safety
35    ///
36    /// Same safety requirements as [`acquire`].
37    unsafe fn reacquire(lock: &L, entry: *mut L::LockEntry, state: &mut Self::GuardState);
38
39    /// Releases the raw synchronization lock, restoring the state.
40    ///
41    /// # Safety
42    ///
43    /// 1. The `entry` pointer must match the exact same stack slot pointer passed to the
44    ///    corresponding `acquire` call.
45    /// 2. The `state` parameter must match the exact same state value returned by the corresponding
46    ///    `acquire` call.
47    /// 3. The caller must guarantee that the current thread actually holds this lock (i.e. we are
48    ///    releasing a lock we currently own).
49    unsafe fn release(lock: &L, entry: *mut L::LockEntry, state: Self::GuardState);
50}
51
52/// Trait defining a raw, un-instrumented synchronization lock abstraction.
53///
54/// Implementors of `RawLock` supply the platform-specific lock storage, in-place pinning
55/// initialization logic, and raw synchronization entry points for lock validation systems.
56pub trait RawLock {
57    /// Flags specifying validation rules for the lock class.
58    const LOCK_FLAGS: lockdep::LockFlags = lockdep::LOCK_FLAGS_NONE;
59
60    /// Opaque stack entry storage type used by the lock validation loop detector (e.g. LockDep).
61    type LockEntry: Default;
62
63    /// Default policy that should be used when acquiring this lock.
64    type DefaultPolicy: LockPolicy<Self>;
65
66    /// Returns a PinInit block to initialize the raw mutex in-place.
67    ///
68    /// # Safety
69    ///
70    /// The caller must ensure that `class_id` is either null or points to a valid,
71    /// static `LockClassId` that remains valid for the lifetime of the lock.
72    unsafe fn init(
73        class_id: *const core::ffi::c_void,
74    ) -> impl PinInit<Self, core::convert::Infallible>
75    where
76        Self: Sized;
77
78    /// Convert the raw mutex reference to a standard c_void pointer for FFI.
79    fn as_mut_ptr(&self) -> *mut core::ffi::c_void;
80}