mu_lib/
atomic.rs

1//! Atomic operations module providing thread-safe operations
2//!
3//! This module provides functions for safe atomic operations in a multi-threaded environment.
4
5#![allow(non_upper_case_globals)]
6#![allow(non_camel_case_types)]
7#![allow(non_snake_case)]
8
9pub use crate::bindings::root::{
10    atomicAddRB, atomicAddAsyncRB, atomicAndRB, atomicAndAsyncRB, atomicCASRB, atomicDecRB,
11    atomicDecAsyncRB, atomicIncRB, atomicIncAsyncRB, atomicMaxRB, atomicMinRB, atomicOrRB,
12    atomicOrAsyncRB, atomicLoadRB, atomicSwapRB, atomicXorRB, atomicXorAsyncRB, atomicOr58RB,
13    atomicAnd58RB, atomicXor58RB, atomicLoad58RB, atomicStore58AsyncRB, atomicSwap58RB,
14    atomicStoreAsyncRB,
15};
16
17/// Function to atomically add a value to the given address
18///
19/// # Arguments
20/// * `address` - Target address
21/// * `value` - Value to add
22///
23/// # Returns
24/// * `i32` - Value after the operation
25///
26/// # Examples
27/// ```
28/// use mu_lib::atomic::atomic_add;
29///
30/// let mut value = 5;
31/// let result = atomic_add(&mut value as *mut i32, 3);
32/// assert_eq!(result, 8);
33/// ```
34pub fn atomic_add(address: *mut i32, value: i32) -> i32 {
35    unsafe { atomicAddRB(address, value) }
36}
37
38/// Function to asynchronously atomically add a value to the given address
39///
40/// # Arguments
41/// * `address` - Target address
42/// * `value` - Value to add
43///
44/// # Returns
45/// * `i32` - Value after the operation
46///
47/// # Examples
48/// ```
49/// use mu_lib::atomic::atomic_add_async;
50///
51/// let mut value = 5;
52/// let result = atomic_add_async(&mut value as *mut i32, 3);
53/// assert_eq!(result, 8);
54/// ```
55pub fn atomic_add_async(address: *mut i32, value: i32) -> i32 {
56    unsafe { atomicAddAsyncRB(address, value) }
57}
58
59/// Function to atomically perform bitwise AND operation
60///
61/// # Arguments
62/// * `address` - Target address
63/// * `value` - Value to AND with
64///
65/// # Returns
66/// * `u32` - Value after the operation
67///
68/// # Examples
69/// ```
70/// use mu_lib::atomic::atomic_and;
71///
72/// let mut value = 5;
73/// let result = atomic_and(&mut value as *mut u32, 3);
74/// assert_eq!(result, 1);
75/// ```
76pub fn atomic_and(address: *mut u32, value: u32) -> u32 {
77    unsafe { atomicAndRB(address, value) }
78}
79
80/// Function to asynchronously atomically perform bitwise AND operation
81///
82/// # Arguments
83/// * `address` - Target address
84/// * `value` - Value to AND with
85///
86/// # Returns
87/// * `u32` - Value after the operation
88///
89/// # Examples
90/// ```
91/// use mu_lib::atomic::atomic_and_async;
92///
93/// let mut value = 5;
94/// let result = atomic_and_async(&mut value as *mut u32, 3);
95/// assert_eq!(result, 1);
96/// ```
97pub fn atomic_and_async(address: *mut u32, value: u32) -> u32 {
98    unsafe { atomicAndAsyncRB(address, value) }
99}
100
101/// Function to atomically decrement a value at the given address
102///
103/// # Arguments
104/// * `address` - Target address
105/// * `value` - Value to decrement by
106///
107/// # Returns
108/// * `i32` - Value after the operation
109///
110/// # Examples
111/// ```
112/// use mu_lib::atomic::atomic_dec;
113///
114/// let mut value = 5;
115/// let result = atomic_dec(&mut value as *mut i32, 3);
116/// assert_eq!(result, 2);
117/// ```
118pub fn atomic_dec(address: *mut i32, value: i32) -> i32 {
119    unsafe { atomicDecRB(address, value) }
120}
121
122/// Function to asynchronously atomically decrement a value at the given address
123///
124/// # Arguments
125/// * `address` - Target address
126/// * `value` - Value to decrement by
127///
128/// # Returns
129/// * `i32` - Value after the operation
130///
131/// # Examples
132/// ```
133/// use mu_lib::atomic::atomic_dec_async;
134///
135/// let mut value = 5;
136/// let result = atomic_dec_async(&mut value as *mut i32, 3);
137/// assert_eq!(result, 2);
138/// ```
139pub fn atomic_dec_async(address: *mut i32, value: i32) -> i32 {
140    unsafe { atomicDecAsyncRB(address, value) }
141}
142
143/// Function to atomically increment a value at the given address
144///
145/// # Arguments
146/// * `address` - Target address
147/// * `value` - Value to increment by
148///
149/// # Returns
150/// * `i32` - Value after the operation
151///
152/// # Examples
153/// ```
154/// use mu_lib::atomic::atomic_inc;
155///
156/// let mut value = 5;
157/// let result = atomic_inc(&mut value as *mut i32, 3);
158/// assert_eq!(result, 8);
159/// ```
160pub fn atomic_inc(address: *mut i32, value: i32) -> i32 {
161    unsafe { atomicIncRB(address, value) }
162}
163
164/// Function to asynchronously atomically increment a value at the given address
165///
166/// # Arguments
167/// * `address` - Target address
168/// * `value` - Value to increment by
169///
170/// # Returns
171/// * `i32` - Value after the operation
172///
173/// # Examples
174/// ```
175/// use mu_lib::atomic::atomic_inc_async;
176///
177/// let mut value = 5;
178/// let result = atomic_inc_async(&mut value as *mut i32, 3);
179/// assert_eq!(result, 8);
180/// ```
181pub fn atomic_inc_async(address: *mut i32, value: i32) -> i32 {
182    unsafe { atomicIncAsyncRB(address, value) }
183}
184
185/// Function to atomically set a value to the maximum of the current value and the given value
186///
187/// # Arguments
188/// * `address` - Target address
189/// * `value` - Value to compare with
190///
191/// # Returns
192/// * `i32` - Value after the operation
193///
194/// # Examples
195/// ```
196/// use mu_lib::atomic::atomic_max;
197///
198/// let mut value = 5;
199/// let result = atomic_max(&mut value as *mut i32, 3);
200/// assert_eq!(result, 5);
201/// ```
202pub fn atomic_max(address: *mut i32, value: i32) -> i32 {
203    unsafe { atomicMaxRB(address, value) }
204}
205
206/// Function to atomically set a value to the minimum of the current value and the given value
207///
208/// # Arguments
209/// * `address` - Target address
210/// * `value` - Value to compare with
211///
212/// # Returns
213/// * `i32` - Value after the operation
214///
215/// # Examples
216/// ```
217/// use mu_lib::atomic::atomic_min;
218///
219/// let mut value = 5;
220/// let result = atomic_min(&mut value as *mut i32, 3);
221/// assert_eq!(result, 3);
222/// ```
223pub fn atomic_min(address: *mut i32, value: i32) -> i32 {
224    unsafe { atomicMinRB(address, value) }
225}
226
227/// Function to atomically perform bitwise OR operation
228///
229/// # Arguments
230/// * `address` - Target address
231/// * `value` - Value to OR with
232///
233/// # Returns
234/// * `u32` - Value after the operation
235///
236/// # Examples
237/// ```
238/// use mu_lib::atomic::atomic_or;
239///
240/// let mut value = 5;
241/// let result = atomic_or(&mut value as *mut u32, 3);
242/// assert_eq!(result, 7);
243/// ```
244pub fn atomic_or(address: *mut u32, value: u32) -> u32 {
245    unsafe { atomicOrRB(address, value) }
246}
247
248/// Function to asynchronously atomically perform bitwise OR operation
249///
250/// # Arguments
251/// * `address` - Target address
252/// * `value` - Value to OR with
253///
254/// # Returns
255/// * `u32` - Value after the operation
256///
257/// # Examples
258/// ```
259/// use mu_lib::atomic::atomic_or_async;
260///
261/// let mut value = 5;
262/// let result = atomic_or_async(&mut value as *mut u32, 3);
263/// assert_eq!(result, 7);
264/// ```
265pub fn atomic_or_async(address: *mut u32, value: u32) -> u32 {
266    unsafe { atomicOrAsyncRB(address, value) }
267}
268
269/// Function to atomically swap a value at the given address
270///
271/// # Arguments
272/// * `address` - Target address
273/// * `value` - New value
274///
275/// # Returns
276/// * `i32` - Previous value at the address
277///
278/// # Examples
279/// ```
280/// use mu_lib::atomic::atomic_swap;
281///
282/// let mut value = 5;
283/// let result = atomic_swap(&mut value as *mut i32, 3);
284/// assert_eq!(result, 5);
285/// ```
286pub fn atomic_swap(address: *mut i32, value: i32) -> i32 {
287    unsafe { atomicSwapRB(address, value) }
288}
289
290/// Function to atomically perform bitwise XOR operation
291///
292/// # Arguments
293/// * `address` - Target address
294/// * `value` - Value to XOR with
295///
296/// # Returns
297/// * `u32` - Value after the operation
298///
299/// # Examples
300/// ```
301/// use mu_lib::atomic::atomic_xor;
302///
303/// let mut value = 5;
304/// let result = atomic_xor(&mut value as *mut u32, 3);
305/// assert_eq!(result, 6);
306/// ```
307pub fn atomic_xor(address: *mut u32, value: u32) -> u32 {
308    unsafe { atomicXorRB(address, value) }
309}
310
311/// Function to asynchronously atomically perform bitwise XOR operation
312///
313/// # Arguments
314/// * `address` - Target address
315/// * `value` - Value to XOR with
316///
317/// # Returns
318/// * `u32` - Value after the operation
319///
320/// # Examples
321/// ```
322/// use mu_lib::atomic::atomic_xor_async;
323///
324/// let mut value = 5;
325/// let result = atomic_xor_async(&mut value as *mut u32, 3);
326/// assert_eq!(result, 6);
327/// ```
328pub fn atomic_xor_async(address: *mut u32, value: u32) -> u32 {
329    unsafe { atomicXorAsyncRB(address, value) }
330}
331
332/// Function to atomically compare and swap a value at the given address
333///
334/// # Arguments
335/// * `address` - Target address
336/// * `val` - New value
337/// * `compare` - Value to compare with
338///
339/// # Returns
340/// * `i32` - Previous value at the address
341///
342/// # Examples
343/// ```
344/// use mu_lib::atomic::atomic_cas;
345///
346/// let mut value = 5;
347/// let result = atomic_cas(&mut value as *mut i32, 3, 5);
348/// assert_eq!(result, 5);
349/// ```
350pub fn atomic_cas(address: *mut i32, val: i32, compare: i32) -> i32 {
351    unsafe { atomicCASRB(address, val, compare) }
352}
353
354/// Function to atomically perform 64-bit bitwise OR operation
355///
356/// # Note
357/// Supported since MX1S
358///
359/// # Arguments
360/// * `address` - Target address
361/// * `value` - Value to OR with
362///
363/// # Returns
364/// * `u64` - Value after the operation
365///
366/// # Examples
367/// ```
368/// use mu_lib::atomic::atomic_or_58;
369///
370/// let mut value: u64 = 5;
371/// let result = atomic_or_58(&mut value as *mut u64, 3);
372/// assert_eq!(result, 7);
373/// ```
374pub fn atomic_or_58(address: *mut u64, value: u64) -> u64 {
375    unsafe { atomicOr58RB(address, value) }
376}
377
378/// Function to atomically perform 64-bit bitwise AND operation
379///
380/// # Note
381/// Supported since MX1S
382///
383/// # Arguments
384/// * `address` - Target address
385/// * `value` - Value to AND with
386///
387/// # Returns
388/// * `u64` - Value after the operation
389///
390/// # Examples
391/// ```
392/// use mu_lib::atomic::atomic_and_58;
393///
394/// let mut value: u64 = 5;
395/// let result = atomic_and_58(&mut value as *mut u64, 3);
396/// assert_eq!(result, 1);
397/// ```
398pub fn atomic_and_58(address: *mut u64, value: u64) -> u64 {
399    unsafe { atomicAnd58RB(address, value) }
400}
401
402/// Function to atomically perform 64-bit bitwise XOR operation
403///
404/// # Note
405/// Supported since MX1S
406///
407/// # Arguments
408/// * `address` - Target address
409/// * `value` - Value to XOR with
410///
411/// # Returns
412/// * `u64` - Value after the operation
413///
414/// # Examples
415/// ```
416/// use mu_lib::atomic::atomic_xor_58;
417///
418/// let mut value: u64 = 5;
419/// let result = atomic_xor_58(&mut value as *mut u64, 3);
420/// assert_eq!(result, 6);
421/// ```
422pub fn atomic_xor_58(address: *mut u64, value: u64) -> u64 {
423    unsafe { atomicXor58RB(address, value) }
424}
425
426/// Function to atomically load a 64-bit value from the given address
427///
428/// # Note
429/// Supported since MX1S
430///
431/// # Arguments
432/// * `address` - Target address
433///
434/// # Returns
435/// * `i64` - Value at the address
436///
437/// # Examples
438/// ```
439/// use mu_lib::atomic::atomic_load_58;
440///
441/// let mut value: i64 = 5;
442/// let result = atomic_load_58(&mut value as *mut i64);
443/// assert_eq!(result, 5);
444/// ```
445pub fn atomic_load_58(address: *mut i64) -> i64 {
446    unsafe { atomicLoad58RB(address) }
447}
448
449/// Function to asynchronously atomically store a 64-bit value to the given address
450///
451/// # Note
452/// Supported since MX1S
453///
454/// # Arguments
455/// * `address` - Target address
456/// * `value` - Value to store
457///
458/// # Returns
459/// * `i64` - Previous value at the address
460///
461/// # Examples
462/// ```
463/// use mu_lib::atomic::atomic_store_58;
464///
465/// let mut value: i64 = 5;
466/// let result = atomic_store_58(&mut value as *mut i64, 10);
467/// assert_eq!(result, 5);
468/// assert_eq!(value, 10);
469/// ```
470pub fn atomic_store_58_async(address: *mut i64, value: i64) -> i64 {
471    unsafe { atomicStore58AsyncRB(address, value) }
472}
473
474/// Function to atomically swap a 64-bit value at the given address
475///
476/// # Note
477/// Supported since MX1S
478///
479/// # Arguments
480/// * `address` - Target address
481/// * `value` - Value to swap with
482///
483/// # Returns
484/// * `i64` - Previous value at the address
485///
486/// # Examples
487/// ```
488/// use mu_lib::atomic::atomic_swap_58;
489///
490/// let mut value: i64 = 5;
491/// let result = atomic_swap_58(&mut value as *mut i64, 10);
492/// assert_eq!(result, 5);
493/// assert_eq!(value, 10);
494/// ```
495pub fn atomic_swap_58(address: *mut i64, value: i64) -> i64 {
496    unsafe { atomicSwap58RB(address, value) }
497}
498
499/// Function to atomically load a 32-bit value from the given address
500///
501/// # Arguments
502/// * `address` - Target address
503///
504/// # Returns
505/// * `i32` - Value at the address
506///
507/// # Examples
508/// ```
509/// use mu_lib::atomic::atomic_load;
510///
511/// let mut value = 5;
512/// let result = atomic_load(&mut value as *mut i32);
513/// assert_eq!(result, 5);
514/// ```
515pub fn atomic_load(address: *mut i32) -> i32 {
516    unsafe { atomicLoadRB(address) }
517}
518
519/// Function to asynchronously atomically store a 32-bit value to the given address
520///
521/// # Note
522/// Supported since MX1S
523///
524/// # Arguments
525/// * `address` - Target address
526/// * `value` - Value to store
527///
528/// # Returns
529/// * `i32` - Previous value at the address
530///
531/// # Examples
532/// ```
533/// use mu_lib::atomic::atomic_store_async;
534///
535/// let mut value = 5;
536/// let result = atomic_store_async(&mut value as *mut i32, 10);
537/// assert_eq!(result, 5);
538/// assert_eq!(value, 10);
539/// ```
540pub fn atomic_store_async(address: *mut i32, value: i32) -> i32 {
541    unsafe { atomicStoreAsyncRB(address, value) }
542}