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}