Skip to main content

ax_runtime/
sync.rs

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