ax_task/sync/bridge/
mutex.rs1use core::{
4 cell::UnsafeCell,
5 mem::MaybeUninit,
6 panic::Location,
7 sync::atomic::{AtomicU8, AtomicU64},
8};
9
10#[cfg(feature = "lockdep")]
11use {
12 crate::sync::lockdep::LockdepMapView, crate::sync::mutex::lockdep::LockdepAcquire,
13 crate::sync::mutex::lockdep::LockdepAcquireRequest,
14};
15
16use super::lockdep::LockClass;
17use crate::sync::mutex::{
18 PI_MUTEX_WAIT_STORAGE_WORDS, PiMutexAlgorithm, PiMutexCoreView, destroy_pi_mutex_storage,
19};
20
21#[derive(Clone, Copy)]
23pub struct PiMutexStorage<'lock> {
24 pub owner: &'lock AtomicU64,
25 pub generation: &'lock AtomicU64,
26 pub wait_state: &'lock AtomicU8,
27 pub wait_words: &'lock UnsafeCell<[MaybeUninit<usize>; PI_MUTEX_WAIT_STORAGE_WORDS]>,
28}
29
30impl<'lock> PiMutexStorage<'lock> {
31 fn core(self) -> PiMutexCoreView<'lock> {
32 PiMutexCoreView::from_parts(
33 self.owner,
34 self.generation,
35 self.wait_state,
36 self.wait_words,
37 )
38 }
39}
40
41pub struct PiMutexStorageMut<'lock> {
43 pub owner: &'lock mut AtomicU64,
44 pub generation: &'lock mut AtomicU64,
45 pub wait_state: &'lock mut AtomicU8,
46 pub wait_words: &'lock mut UnsafeCell<[MaybeUninit<usize>; PI_MUTEX_WAIT_STORAGE_WORDS]>,
47}
48
49pub struct MutexAcquireRequest<'lock> {
51 pub storage: PiMutexStorage<'lock>,
52 pub next_waiter_sequence: &'lock AtomicU64,
53 pub class: LockClass<'lock>,
54 pub lock_addr: usize,
55 pub subclass: u32,
56 pub caller: &'static Location<'static>,
57}
58
59pub fn mutex_acquire(request: MutexAcquireRequest<'_>) {
61 let lockdep = prepare_lockdep(&request, false);
62 let algorithm = PiMutexAlgorithm::new(request.storage.core(), request.next_waiter_sequence);
63 algorithm.lock_pi();
64 finish_lockdep(lockdep, true);
65}
66
67pub fn mutex_try_acquire(request: MutexAcquireRequest<'_>) -> bool {
69 let lockdep = prepare_lockdep(&request, true);
70 let algorithm = PiMutexAlgorithm::new(request.storage.core(), request.next_waiter_sequence);
71 let acquired = algorithm.try_lock_pi();
72 finish_lockdep(lockdep, acquired);
73 acquired
74}
75
76pub fn mutex_release(storage: PiMutexStorage<'_>, lock_addr: usize) {
78 release_lockdep(lock_addr);
79 unsafe {
80 PiMutexAlgorithm::unlock_core(storage.core());
83 }
84}
85
86pub fn mutex_force_release(storage: PiMutexStorage<'_>, lock_addr: usize) {
88 mutex_release(storage, lock_addr);
89}
90
91pub fn mutex_is_owned_by_current(storage: PiMutexStorage<'_>) -> bool {
93 PiMutexAlgorithm::core_is_owned_by_current(storage.core())
94}
95
96pub fn mutex_is_locked(storage: PiMutexStorage<'_>) -> bool {
98 PiMutexAlgorithm::core_is_locked(storage.core())
99}
100
101pub fn mutex_destroy(storage: PiMutexStorageMut<'_>) {
103 destroy_pi_mutex_storage(
104 storage.owner,
105 storage.generation,
106 storage.wait_state,
107 storage.wait_words,
108 );
109}
110
111#[cfg(feature = "lockdep")]
112fn prepare_lockdep(request: &MutexAcquireRequest<'_>, is_try: bool) -> LockdepAcquire {
113 LockdepAcquire::prepare_view(LockdepAcquireRequest {
114 map: LockdepMapView::new(request.class.class_id, request.class.class_key),
115 addr: request.lock_addr,
116 subclass: request.subclass,
117 is_try,
118 caller: request.caller,
119 })
120}
121
122#[cfg(not(feature = "lockdep"))]
123#[derive(Clone, Copy)]
124struct LockdepAcquire;
125
126#[cfg(not(feature = "lockdep"))]
127fn prepare_lockdep(request: &MutexAcquireRequest<'_>, is_try: bool) -> LockdepAcquire {
128 let _ = (request, is_try);
129 LockdepAcquire
130}
131
132fn finish_lockdep(lockdep: LockdepAcquire, acquired: bool) {
133 #[cfg(feature = "lockdep")]
134 lockdep.finish(acquired);
135
136 #[cfg(not(feature = "lockdep"))]
137 let _ = (lockdep, acquired);
138}
139
140fn release_lockdep(lock_addr: usize) {
141 #[cfg(feature = "lockdep")]
142 crate::sync::mutex::lockdep::release_external(lock_addr);
143
144 #[cfg(not(feature = "lockdep"))]
145 let _ = lock_addr;
146}