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.
10///
11/// # Safety
12///
13/// Implementors must guarantee that [`acquire`](Self::acquire) and [`reacquire`](Self::reacquire)
14/// establish exclusive mutual exclusion on `lock` until the matching [`release`](Self::release)
15/// call completes.
16pub unsafe trait LockPolicy<L: RawLock + ?Sized> {
17    /// Arguments passed when acquiring the lock under this policy.
18    type AcquireArgs: Copy;
19
20    /// State returned from lock acquisition and subsequently passed to lock release.
21    type GuardState: Default + Copy;
22
23    /// Acquires the raw synchronization lock under a type-level lock class.
24    ///
25    /// # Safety
26    ///
27    /// 1. The `entry` pointer must point to a valid, exclusive, stack-allocated `LockEntry` slot
28    ///    which will be registered in the thread's active list.
29    /// 2. The caller must ensure that the `entry` memory remains pinned on the stack and is not
30    ///    dropped or moved until the matching `release` call completes.
31    unsafe fn acquire(
32        lock: &L,
33        entry: *mut L::LockEntry,
34        args: Self::AcquireArgs,
35    ) -> Self::GuardState;
36
37    /// Re-acquires the raw synchronization lock using existing guard state (e.g. after
38    /// `call_unlocked`).
39    ///
40    /// # Safety
41    ///
42    /// Same safety requirements as [`acquire`].
43    unsafe fn reacquire(lock: &L, entry: *mut L::LockEntry, state: &mut Self::GuardState);
44
45    /// Releases the raw synchronization lock, restoring the state.
46    ///
47    /// # Safety
48    ///
49    /// 1. The `entry` pointer must match the exact same stack slot pointer passed to the
50    ///    corresponding `acquire` call.
51    /// 2. The `state` parameter must match the exact same state value returned by the corresponding
52    ///    `acquire` call.
53    /// 3. The caller must guarantee that the current thread actually holds this lock (i.e. we are
54    ///    releasing a lock we currently own).
55    unsafe fn release(lock: &L, entry: *mut L::LockEntry, state: Self::GuardState);
56}
57
58/// Trait defining a raw, un-instrumented synchronization lock abstraction.
59///
60/// Implementors of `RawLock` supply the platform-specific lock storage, in-place pinning
61/// initialization logic, and raw synchronization entry points for lock validation systems.
62///
63/// # Safety
64///
65/// Implementors must represent a physical synchronization primitive with non-zero size whose
66/// [`as_mut_ptr`](Self::as_mut_ptr) uniquely identifies the underlying lock storage for the
67/// lifetime of `&self`.
68pub unsafe trait RawLock {
69    /// Flags specifying validation rules for the lock class.
70    const LOCK_FLAGS: lockdep::LockFlags = lockdep::LOCK_FLAGS_NONE;
71
72    /// Opaque stack entry storage type used by the lock validation loop detector (e.g. LockDep).
73    type LockEntry: Default;
74
75    /// Default policy that should be used when acquiring this lock.
76    type DefaultPolicy: LockPolicy<Self>;
77
78    /// Returns a PinInit block to initialize the raw mutex in-place.
79    ///
80    /// # Safety
81    ///
82    /// The caller must ensure that `class_id` is either null or points to a valid,
83    /// static `LockClassId` that remains valid for the lifetime of the lock.
84    unsafe fn init(
85        class_id: *const core::ffi::c_void,
86    ) -> impl PinInit<Self, core::convert::Infallible>
87    where
88        Self: Sized;
89
90    /// Convert the raw mutex reference to a standard c_void pointer for FFI.
91    fn as_mut_ptr(&self) -> *mut core::ffi::c_void;
92}