Skip to main content

ax_runtime/
sync.rs

1//! Native ArceOS lock facade and `ax-sync` bridge provider.
2
3#[cfg(feature = "multitask")]
4use core::sync::atomic::{AtomicPtr, AtomicU64};
5use core::{
6    panic::Location,
7    sync::atomic::{AtomicBool, AtomicUsize},
8};
9
10pub use ax_task::sync::api::*;
11
12struct RuntimeContextOps;
13
14#[ax_crate_interface::impl_interface]
15impl ax_sync::interface::ContextOps for RuntimeContextOps {
16    fn enter(context: u8) -> usize {
17        ax_task::sync::bridge::context_enter(context)
18    }
19
20    fn exit(context: u8, state: usize) {
21        ax_task::sync::bridge::context_exit(context, state);
22    }
23
24    fn exit_preempt_from_irq_return(state: usize) {
25        ax_task::sync::bridge::preempt_exit_from_irq_return(state);
26    }
27}
28
29struct RuntimeSpinOps;
30
31#[ax_crate_interface::impl_interface]
32impl ax_sync::interface::SpinOps for RuntimeSpinOps {
33    fn acquire(
34        locked: &AtomicBool,
35        metadata: &ax_sync::interface::LockMetadata,
36        lock_addr: usize,
37        context: u8,
38        subclass: u32,
39        is_try: bool,
40        caller: &'static Location<'static>,
41    ) -> ax_sync::interface::AcquireResult {
42        let (acquired, context_state) =
43            ax_task::sync::bridge::spin_acquire(ax_task::sync::bridge::SpinAcquireRequest {
44                locked,
45                class: ax_task::sync::bridge::LockClass {
46                    class_id: metadata.class_id(),
47                    class_key: metadata.class_key(),
48                },
49                lock_addr,
50                context,
51                subclass,
52                is_try,
53                caller,
54            });
55        ax_sync::interface::AcquireResult::new(acquired, context_state)
56    }
57
58    fn release(locked: &AtomicBool, lock_addr: usize, context: u8, context_state: usize) {
59        ax_task::sync::bridge::spin_release(locked, lock_addr, context, context_state);
60    }
61
62    fn force_release(locked: &AtomicBool, lock_addr: usize, context: u8) {
63        ax_task::sync::bridge::spin_force_release(locked, lock_addr, context);
64    }
65
66    fn is_locked(locked: &AtomicBool) -> bool {
67        ax_task::sync::bridge::spin_is_locked(locked)
68    }
69}
70
71struct RuntimeRwLockOps;
72
73#[ax_crate_interface::impl_interface]
74impl ax_sync::interface::RwLockOps for RuntimeRwLockOps {
75    fn acquire(
76        state: &AtomicUsize,
77        metadata: &ax_sync::interface::LockMetadata,
78        lock_addr: usize,
79        context: u8,
80        mode: u8,
81        is_try: bool,
82        caller: &'static Location<'static>,
83    ) -> ax_sync::interface::AcquireResult {
84        let (acquired, context_state) =
85            ax_task::sync::bridge::rwlock_acquire(ax_task::sync::bridge::RwLockAcquireRequest {
86                state,
87                class: ax_task::sync::bridge::LockClass {
88                    class_id: metadata.class_id(),
89                    class_key: metadata.class_key(),
90                },
91                lock_addr,
92                context,
93                mode,
94                is_try,
95                caller,
96            });
97        ax_sync::interface::AcquireResult::new(acquired, context_state)
98    }
99
100    fn release(state: &AtomicUsize, lock_addr: usize, context: u8, context_state: usize, mode: u8) {
101        ax_task::sync::bridge::rwlock_release(state, lock_addr, context, context_state, mode);
102    }
103
104    fn force_read_decrement(state: &AtomicUsize, lock_addr: usize, context: u8) {
105        ax_task::sync::bridge::rwlock_force_read_decrement(state, lock_addr, context);
106    }
107}
108
109#[cfg(feature = "multitask")]
110struct RuntimeMutexOps;
111
112#[cfg(feature = "multitask")]
113#[ax_crate_interface::impl_interface]
114impl ax_sync::interface::MutexOps for RuntimeMutexOps {
115    fn acquire(
116        wait_queue: &AtomicPtr<()>,
117        owner_id: &AtomicU64,
118        metadata: &ax_sync::interface::LockMetadata,
119        lock_addr: usize,
120        subclass: u32,
121        is_try: bool,
122        caller: &'static Location<'static>,
123    ) -> bool {
124        ax_task::sync::bridge::mutex_acquire(ax_task::sync::bridge::MutexAcquireRequest {
125            wait_queue,
126            owner_id,
127            class: ax_task::sync::bridge::LockClass {
128                class_id: metadata.class_id(),
129                class_key: metadata.class_key(),
130            },
131            lock_addr,
132            subclass,
133            is_try,
134            caller,
135        })
136    }
137
138    fn release(wait_queue: &AtomicPtr<()>, owner_id: &AtomicU64, lock_addr: usize) {
139        ax_task::sync::bridge::mutex_release(wait_queue, owner_id, lock_addr);
140    }
141
142    fn force_release(wait_queue: &AtomicPtr<()>, owner_id: &AtomicU64, lock_addr: usize) {
143        ax_task::sync::bridge::mutex_force_release(wait_queue, owner_id, lock_addr);
144    }
145
146    fn is_owned_by_current(owner_id: &AtomicU64) -> bool {
147        ax_task::sync::bridge::mutex_is_owned_by_current(owner_id)
148    }
149
150    fn is_locked(owner_id: &AtomicU64) -> bool {
151        ax_task::sync::bridge::mutex_is_locked(owner_id)
152    }
153
154    fn drop_wait_queue(wait_queue: *mut ()) {
155        ax_task::sync::bridge::mutex_drop_wait_queue(wait_queue);
156    }
157}
158
159struct RuntimeLockdepOps;
160
161#[ax_crate_interface::impl_interface]
162impl ax_sync::interface::LockdepOps for RuntimeLockdepOps {
163    fn set_trace_enabled(enabled: bool) {
164        ax_task::sync::bridge::set_lockdep_trace_enabled(enabled);
165    }
166
167    fn dump_trace() {
168        ax_task::sync::bridge::dump_lockdep_trace();
169    }
170}