1 /* 2 * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRFX_ATOMIC_H__ 33 #define NRFX_ATOMIC_H__ 34 35 #include <nrfx.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** 42 * @defgroup nrfx_atomic Atomic operations API 43 * @ingroup nrfx 44 * @{ 45 * 46 * @brief This module implements C11 stdatomic.h simplified API. 47 * 48 * At this point, only Cortex-M3 and M4 cores are supported (LDREX/STREX instructions). 49 * Atomic types are limited to @ref nrfx_atomic_u32_t and @ref nrfx_atomic_flag_t. 50 */ 51 52 53 /** @brief Atomic 32-bit unsigned type. */ 54 typedef volatile uint32_t nrfx_atomic_u32_t; 55 56 /** @brief Atomic 1-bit flag type (technically 32-bit). */ 57 typedef volatile uint32_t nrfx_atomic_flag_t; 58 59 /** 60 * @brief Function for storing a value to an atomic object and returning its previous value. 61 * 62 * @param[in] p_data Atomic memory pointer. 63 * @param[in] value Value to store. 64 * 65 * @return Previous value stored in the atomic object. 66 */ 67 uint32_t nrfx_atomic_u32_fetch_store(nrfx_atomic_u32_t * p_data, uint32_t value); 68 69 /** 70 * @brief Function for storing a value to an atomic object and returning its new value. 71 * 72 * @param[in] p_data Atomic memory pointer. 73 * @param[in] value Value to store. 74 * 75 * @return New value stored in the atomic object. 76 */ 77 uint32_t nrfx_atomic_u32_store(nrfx_atomic_u32_t * p_data, uint32_t value); 78 79 /** 80 * @brief Function for running a logical OR operation on an atomic object 81 * and returning its previous value. 82 * 83 * @param[in] p_data Atomic memory pointer. 84 * @param[in] value Value of the second operand in the OR operation. 85 * 86 * @return Previous value stored in the atomic object. 87 */ 88 uint32_t nrfx_atomic_u32_fetch_or(nrfx_atomic_u32_t * p_data, uint32_t value); 89 90 /** 91 * @brief Function for running a logical OR operation on an atomic object 92 * and returning its new value. 93 * 94 * @param[in] p_data Atomic memory pointer. 95 * @param[in] value Value of the second operand in the OR operation. 96 * 97 * @return New value stored in the atomic object. 98 */ 99 uint32_t nrfx_atomic_u32_or(nrfx_atomic_u32_t * p_data, uint32_t value); 100 101 /** 102 * @brief Function for running a logical AND operation on an atomic object 103 * and returning its previous value. 104 * 105 * @param[in] p_data Atomic memory pointer. 106 * @param[in] value Value of the second operand in the AND operation. 107 * 108 * @return Previous value stored in the atomic object. 109 */ 110 uint32_t nrfx_atomic_u32_fetch_and(nrfx_atomic_u32_t * p_data, uint32_t value); 111 112 /** 113 * @brief Function for running a logical AND operation on an atomic object 114 * and returning its new value. 115 * 116 * @param[in] p_data Atomic memory pointer. 117 * @param[in] value Value of the second operand in the AND operation. 118 * 119 * @return New value stored in the atomic object. 120 */ 121 uint32_t nrfx_atomic_u32_and(nrfx_atomic_u32_t * p_data, uint32_t value); 122 123 /** 124 * @brief Function for running a logical XOR operation on an atomic object 125 * and returning its previous value. 126 * 127 * @param[in] p_data Atomic memory pointer. 128 * @param[in] value Value of the second operand in the XOR operation. 129 * 130 * @return Previous value stored in the atomic object. 131 */ 132 uint32_t nrfx_atomic_u32_fetch_xor(nrfx_atomic_u32_t * p_data, uint32_t value); 133 134 /** 135 * @brief Function for running a logical XOR operation on an atomic object 136 * and returning its new value. 137 * 138 * @param[in] p_data Atomic memory pointer. 139 * @param[in] value Value of the second operand in the XOR operation. 140 * 141 * @return New value stored in the atomic object. 142 */ 143 uint32_t nrfx_atomic_u32_xor(nrfx_atomic_u32_t * p_data, uint32_t value); 144 145 /** 146 * @brief Function for running an arithmetic ADD operation on an atomic object 147 * and returning its previous value. 148 * 149 * @param[in] p_data Atomic memory pointer. 150 * @param[in] value Value of the second operand in the ADD operation. 151 * 152 * @return Previous value stored in the atomic object. 153 */ 154 uint32_t nrfx_atomic_u32_fetch_add(nrfx_atomic_u32_t * p_data, uint32_t value); 155 156 /** 157 * @brief Function for running an arithmetic ADD operation on an atomic object 158 * and returning its new value. 159 * 160 * @param[in] p_data Atomic memory pointer. 161 * @param[in] value Value of the second operand in the ADD operation. 162 * 163 * @return New value stored in the atomic object. 164 */ 165 uint32_t nrfx_atomic_u32_add(nrfx_atomic_u32_t * p_data, uint32_t value); 166 167 /** 168 * @brief Function for running an arithmetic SUB operation on an atomic object 169 * and returning its previous value. 170 * 171 * @param[in] p_data Atomic memory pointer. 172 * @param[in] value Value of the second operand in the SUB operation. 173 * 174 * @return Old value stored in the atomic object. 175 */ 176 uint32_t nrfx_atomic_u32_fetch_sub(nrfx_atomic_u32_t * p_data, uint32_t value); 177 178 /** 179 * @brief Function for running an arithmetic SUB operation on an atomic object 180 * and returning its new value. 181 * 182 * @param[in] p_data Atomic memory pointer. 183 * @param[in] value Value of the second operand in the SUB operation. 184 * 185 * @return New value stored in the atomic object. 186 */ 187 uint32_t nrfx_atomic_u32_sub(nrfx_atomic_u32_t * p_data, uint32_t value); 188 189 /** 190 * @brief Function for atomic conditional value replacement. 191 * 192 * Atomically compares the value pointed to by @p p_data with the value pointed to by @p p_expected. 193 * If those are equal, replaces the former with desired. Otherwise, loads the actual value 194 * pointed to by @p p_data into @p *p_expected. 195 * 196 * @param p_data Atomic memory pointer to test and modify. 197 * @param p_expected Pointer to the test value. 198 * @param desired Value to be stored to atomic memory. 199 * 200 * @retval true @p *p_data was equal to @p *p_expected. 201 * @retval false @p *p_data was not equal to @p *p_expected. 202 */ 203 bool nrfx_atomic_u32_cmp_exch(nrfx_atomic_u32_t * p_data, 204 uint32_t * p_expected, 205 uint32_t desired); 206 207 /** 208 * @brief Function for running an arithmetic SUB operation on an atomic object 209 * if object >= value, and returning its previous value. 210 * 211 * @param[in] p_data Atomic memory pointer. 212 * @param[in] value Value of the second operand in the SUB operation. 213 * 214 * @return Previous value stored in the atomic object. 215 */ 216 uint32_t nrfx_atomic_u32_fetch_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value); 217 218 /** 219 * @brief Function for running an arithmetic SUB operation on an atomic object 220 * if object >= value, and returning its new value. 221 * 222 * @param[in] p_data Atomic memory pointer. 223 * @param[in] value Value of the second operand in the SUB operation. 224 * 225 * @return New value stored in the atomic object. 226 */ 227 uint32_t nrfx_atomic_u32_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value); 228 229 /** 230 * @brief Function for running a logical one bit flag set operation 231 * on an atomic object and returning its previous value. 232 * 233 * @param[in] p_data Atomic flag memory pointer. 234 * 235 * @return Previous flag value. 236 */ 237 uint32_t nrfx_atomic_flag_set_fetch(nrfx_atomic_flag_t * p_data); 238 239 /** 240 * @brief Function for running a logical one bit flag set operation 241 * on an atomic object and returning its new value. 242 * 243 * @param[in] p_data Atomic flag memory pointer. 244 * 245 * @return New flag value. 246 */ 247 uint32_t nrfx_atomic_flag_set(nrfx_atomic_flag_t * p_data); 248 249 /** 250 * @brief Function for running a logical one bit flag clear operation 251 * on an atomic object and returning its previous value. 252 * 253 * @param[in] p_data Atomic flag memory pointer. 254 * 255 * @return Previous flag value. 256 */ 257 uint32_t nrfx_atomic_flag_clear_fetch(nrfx_atomic_flag_t * p_data); 258 259 /** 260 * @brief Function for running a logical one bit flag clear operation 261 * on an atomic object and returning its new value. 262 * 263 * @param[in] p_data Atomic flag memory pointer. 264 * 265 * @return New flag value. 266 */ 267 uint32_t nrfx_atomic_flag_clear(nrfx_atomic_flag_t * p_data); 268 269 /** @} */ 270 271 #ifdef __cplusplus 272 } 273 #endif 274 275 #endif // NRFX_ATOMIC_H__ 276