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