1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #ifndef ATOMICS_H
7 #define ATOMICS_H
8 
9 #include <stdbool.h>
10 #include <stdint.h>
11 
12 /*
13  * Atomically adds @val to the 64-bit value stored at memory location @loc.
14  */
atomic_add_64(uint64_t * loc,long val)15 static inline void atomic_add_64(uint64_t *loc, long val)
16 {
17 	*loc = *loc + val;
18 }
19 
20 /*
21  * Atomically adds @val to the 64-bit value stored at memory location @loc.
22  * Stores to memory with release semantics.
23  * Returns the old value.
24  */
atomic_load_add_release_64(uint64_t * loc,long val)25 static inline unsigned long atomic_load_add_release_64(uint64_t *loc, long val)
26 {
27 	unsigned long old_val = *loc;
28 
29 	*loc = *loc + val;
30 	return old_val;
31 }
32 
33 /*
34  * Atomically set bit @bit in value pointed to by @val with release semantics.
35  */
atomic_bit_set_release_64(uint64_t * loc,int bit)36 static inline void atomic_bit_set_release_64(uint64_t *loc, int bit)
37 {
38 	uint64_t mask = (1UL << bit);
39 
40 	*loc = *loc | mask;
41 }
42 
43 /*
44  * Atomically clear bit @bit in value pointed to by @loc with release semantics.
45  */
atomic_bit_clear_release_64(uint64_t * loc,int bit)46 static inline void atomic_bit_clear_release_64(uint64_t *loc, int bit)
47 {
48 	uint64_t mask = ~((uint64_t)(1UL << bit));
49 
50 	*loc = *loc & mask;
51 }
52 
53 /*
54  * Test bit @bit in value pointed to by @loc with acquire semantics.
55  */
atomic_test_bit_acquire_64(uint64_t * loc,int bit)56 static inline bool atomic_test_bit_acquire_64(uint64_t *loc, int bit)
57 {
58 	uint64_t val = *loc;
59 	uint64_t mask = (1UL << bit);
60 
61 	return ((val & mask) != 0UL);
62 }
63 
64 /*
65  * Atomically set bit @bit in value pointed to by @val
66  * with acquire and release semantics.
67  * Return True if the previous state of @bit was 1, False otherwise.
68  */
atomic_bit_set_acquire_release_64(uint64_t * loc,int bit)69 static inline bool atomic_bit_set_acquire_release_64(uint64_t *loc, int bit)
70 {
71 	uint64_t mask = (1UL << bit);
72 	unsigned long old_val = *loc & mask;
73 
74 	*loc |= mask;
75 	return (old_val != 0UL);
76 }
77 
78 #endif /* ATOMICS_H */
79