1 /**
2 * @brief Atomically set a bit.
3 *
4 * Atomically set bit number @a bit of @a target.
5 * The target may be a single atomic variable or an array of them.
6 *
7 * @param target Address of atomic variable or array.
8 * @param bit Bit number (starting from 0).
9 *
10 * @return N/A
11 */
12
13 /*
14 * Copyright (c) 2016 Intel Corporation
15 * Copyright (c) 2011-2014 Wind River Systems, Inc.
16 * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
17 *
18 * SPDX-License-Identifier: Apache-2.0
19 */
20
21 #include "mesh_atomic.h"
22 #include "mesh_mutex.h"
23
24 #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN
25
26 /**
27 *
28 * @brief Atomic get primitive
29 *
30 * @param target memory location to read from
31 *
32 * This routine provides the atomic get primitive to atomically read
33 * a value from <target>. It simply does an ordinary load. Note that <target>
34 * is expected to be aligned to a 4-byte boundary.
35 *
36 * @return The value read from <target>
37 */
bt_mesh_atomic_get(const bt_mesh_atomic_t * target)38 bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target)
39 {
40 return *target;
41 }
42
43 /**
44 *
45 * @brief Atomic get-and-set primitive
46 *
47 * This routine provides the atomic set operator. The <value> is atomically
48 * written at <target> and the previous value at <target> is returned.
49 *
50 * @param target the memory location to write to
51 * @param value the value to write
52 *
53 * @return The previous value from <target>
54 */
bt_mesh_atomic_set(bt_mesh_atomic_t * target,bt_mesh_atomic_val_t value)55 bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
56 {
57 bt_mesh_atomic_val_t ret = 0;
58
59 bt_mesh_atomic_lock();
60
61 ret = *target;
62 *target = value;
63
64 bt_mesh_atomic_unlock();
65
66 return ret;
67 }
68
69 /**
70 *
71 * @brief Atomic bitwise inclusive OR primitive
72 *
73 * This routine provides the atomic bitwise inclusive OR operator. The <value>
74 * is atomically bitwise OR'ed with the value at <target>, placing the result
75 * at <target>, and the previous value at <target> is returned.
76 *
77 * @param target the memory location to be modified
78 * @param value the value to OR
79 *
80 * @return The previous value from <target>
81 */
bt_mesh_atomic_or(bt_mesh_atomic_t * target,bt_mesh_atomic_val_t value)82 bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
83 {
84 bt_mesh_atomic_val_t ret = 0;
85
86 bt_mesh_atomic_lock();
87
88 ret = *target;
89 *target |= value;
90
91 bt_mesh_atomic_unlock();
92
93 return ret;
94 }
95
96 /**
97 *
98 * @brief Atomic bitwise AND primitive
99 *
100 * This routine provides the atomic bitwise AND operator. The <value> is
101 * atomically bitwise AND'ed with the value at <target>, placing the result
102 * at <target>, and the previous value at <target> is returned.
103 *
104 * @param target the memory location to be modified
105 * @param value the value to AND
106 *
107 * @return The previous value from <target>
108 */
bt_mesh_atomic_and(bt_mesh_atomic_t * target,bt_mesh_atomic_val_t value)109 bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
110 {
111 bt_mesh_atomic_val_t ret = 0;
112
113 bt_mesh_atomic_lock();
114
115 ret = *target;
116 *target &= value;
117
118 bt_mesh_atomic_unlock();
119
120 return ret;
121 }
122
123 /**
124 *
125 * @brief Atomic decrement primitive
126 *
127 * @param target memory location to decrement
128 *
129 * This routine provides the atomic decrement operator. The value at <target>
130 * is atomically decremented by 1, and the old value from <target> is returned.
131 *
132 * @return The value from <target> prior to the decrement
133 */
bt_mesh_atomic_dec(bt_mesh_atomic_t * target)134 bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target)
135 {
136 bt_mesh_atomic_val_t ret = 0;
137
138 bt_mesh_atomic_lock();
139
140 ret = *target;
141 (*target)--;
142
143 bt_mesh_atomic_unlock();
144
145 return ret;
146 }
147
148 /**
149 *
150 * @brief Atomic increment primitive
151 *
152 * @param target memory location to increment
153 *
154 * This routine provides the atomic increment operator. The value at <target>
155 * is atomically incremented by 1, and the old value from <target> is returned.
156 *
157 * @return The value from <target> before the increment
158 */
bt_mesh_atomic_inc(bt_mesh_atomic_t * target)159 bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
160 {
161 bt_mesh_atomic_val_t ret = 0;
162
163 bt_mesh_atomic_lock();
164
165 ret = *target;
166 (*target)++;
167
168 bt_mesh_atomic_unlock();
169
170 return ret;
171 }
172
173 #endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */
174