1 /* 2 * Copyright (c) 2016 - 2018, 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 /** 54 * @brief Atomic 32-bit unsigned type. 55 */ 56 typedef volatile uint32_t nrfx_atomic_u32_t; 57 58 /** 59 * @brief Atomic 1-bit flag type (technically 32-bit). 60 */ 61 typedef volatile uint32_t nrfx_atomic_flag_t; 62 63 /** 64 * @brief Function for storing a value to an atomic object and returning its previous value. 65 * 66 * @param[in] p_data Atomic memory pointer. 67 * @param[in] value Value to store. 68 * 69 * @return Previous value stored in the atomic object. 70 */ 71 uint32_t nrfx_atomic_u32_fetch_store(nrfx_atomic_u32_t * p_data, uint32_t value); 72 73 /** 74 * @brief Function for storing a value to an atomic object and returning its new value. 75 * 76 * @param[in] p_data Atomic memory pointer. 77 * @param[in] value Value to store. 78 * 79 * @return New value stored in the atomic object. 80 */ 81 uint32_t nrfx_atomic_u32_store(nrfx_atomic_u32_t * p_data, uint32_t value); 82 83 /** 84 * @brief Function for running a logical OR operation on an atomic object 85 * and returning its previous value. 86 * 87 * @param[in] p_data Atomic memory pointer. 88 * @param[in] value Value of the second operand in the OR operation. 89 * 90 * @return Previous value stored in the atomic object. 91 */ 92 uint32_t nrfx_atomic_u32_fetch_or(nrfx_atomic_u32_t * p_data, uint32_t value); 93 94 /** 95 * @brief Function for running a logical OR operation on an atomic object 96 * and returning its new value. 97 * 98 * @param[in] p_data Atomic memory pointer. 99 * @param[in] value Value of the second operand in the OR operation. 100 * 101 * @return New value stored in the atomic object. 102 */ 103 uint32_t nrfx_atomic_u32_or(nrfx_atomic_u32_t * p_data, uint32_t value); 104 105 /** 106 * @brief Function for running a logical AND operation on an atomic object 107 * and returning its previous value. 108 * 109 * @param[in] p_data Atomic memory pointer. 110 * @param[in] value Value of the second operand in the AND operation. 111 * 112 * @return Previous value stored in the atomic object. 113 */ 114 uint32_t nrfx_atomic_u32_fetch_and(nrfx_atomic_u32_t * p_data, uint32_t value); 115 116 /** 117 * @brief Function for running a logical AND operation on an atomic object 118 * and returning its new value. 119 * 120 * @param[in] p_data Atomic memory pointer. 121 * @param[in] value Value of the second operand in the AND operation. 122 * 123 * @return New value stored in the atomic object. 124 */ 125 uint32_t nrfx_atomic_u32_and(nrfx_atomic_u32_t * p_data, uint32_t value); 126 127 /** 128 * @brief Function for running a logical XOR operation on an atomic object 129 * and returning its previous value. 130 * 131 * @param[in] p_data Atomic memory pointer. 132 * @param[in] value Value of the second operand in the XOR operation. 133 * 134 * @return Previous value stored in the atomic object. 135 */ 136 uint32_t nrfx_atomic_u32_fetch_xor(nrfx_atomic_u32_t * p_data, uint32_t value); 137 138 /** 139 * @brief Function for running a logical XOR operation on an atomic object 140 * and returning its new value. 141 * 142 * @param[in] p_data Atomic memory pointer. 143 * @param[in] value Value of the second operand in the XOR operation. 144 * 145 * @return New value stored in the atomic object. 146 */ 147 uint32_t nrfx_atomic_u32_xor(nrfx_atomic_u32_t * p_data, uint32_t value); 148 149 /** 150 * @brief Function for running an arithmetic ADD operation on an atomic object 151 * and returning its previous value. 152 * 153 * @param[in] p_data Atomic memory pointer. 154 * @param[in] value Value of the second operand in the ADD operation. 155 * 156 * @return Previous value stored in the atomic object. 157 */ 158 uint32_t nrfx_atomic_u32_fetch_add(nrfx_atomic_u32_t * p_data, uint32_t value); 159 160 /** 161 * @brief Function for running an arithmetic ADD operation on an atomic object 162 * and returning its new value. 163 * 164 * @param[in] p_data Atomic memory pointer. 165 * @param[in] value Value of the second operand in the ADD operation. 166 * 167 * @return New value stored in the atomic object. 168 */ 169 uint32_t nrfx_atomic_u32_add(nrfx_atomic_u32_t * p_data, uint32_t value); 170 171 /** 172 * @brief Function for running an arithmetic SUB operation on an atomic object 173 * and returning its previous value. 174 * 175 * @param[in] p_data Atomic memory pointer. 176 * @param[in] value Value of the second operand in the SUB operation. 177 * 178 * @return Old value stored in the atomic object. 179 */ 180 uint32_t nrfx_atomic_u32_fetch_sub(nrfx_atomic_u32_t * p_data, uint32_t value); 181 182 /** 183 * @brief Function for running an arithmetic SUB operation on an atomic object 184 * and returning its new value. 185 * 186 * @param[in] p_data Atomic memory pointer. 187 * @param[in] value Value of the second operand in the SUB operation. 188 * 189 * @return New value stored in the atomic object. 190 */ 191 uint32_t nrfx_atomic_u32_sub(nrfx_atomic_u32_t * p_data, uint32_t value); 192 193 /** 194 * @brief Function for atomic conditional value replacement. 195 * 196 * Atomically compares the value pointed to by @p p_data with the value pointed to by @p p_expected. 197 * If those are equal, replaces the former with desired. Otherwise, loads the actual value 198 * pointed to by @p p_data into @p *p_expected. 199 * 200 * @param p_data Atomic memory pointer to test and modify. 201 * @param p_expected Pointer to the test value. 202 * @param desired Value to be stored to atomic memory. 203 * 204 * @retval true @p *p_data was equal to @p *p_expected. 205 * @retval false @p *p_data was not equal to @p *p_expected. 206 */ 207 bool nrfx_atomic_u32_cmp_exch(nrfx_atomic_u32_t * p_data, 208 uint32_t * p_expected, 209 uint32_t desired); 210 211 /** 212 * @brief Function for running an arithmetic SUB operation on an atomic object 213 * if object >= value, and returning its previous value. 214 * 215 * @param[in] p_data Atomic memory pointer. 216 * @param[in] value Value of the second operand in the SUB operation. 217 * 218 * @return Previous value stored in the atomic object. 219 */ 220 uint32_t nrfx_atomic_u32_fetch_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value); 221 222 /** 223 * @brief Function for running an arithmetic SUB operation on an atomic object 224 * if object >= value, and returning its new value. 225 * 226 * @param[in] p_data Atomic memory pointer. 227 * @param[in] value Value of the second operand in the SUB operation. 228 * 229 * @return New value stored in the atomic object. 230 */ 231 uint32_t nrfx_atomic_u32_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value); 232 233 /** 234 * @brief Function for running a logical one bit flag set operation 235 * on an atomic object and returning its previous value. 236 * 237 * @param[in] p_data Atomic flag memory pointer. 238 * 239 * @return Previous flag value. 240 */ 241 uint32_t nrfx_atomic_flag_set_fetch(nrfx_atomic_flag_t * p_data); 242 243 /** 244 * @brief Function for running a logical one bit flag set operation 245 * on an atomic object and returning its new value. 246 * 247 * @param[in] p_data Atomic flag memory pointer. 248 * 249 * @return New flag value. 250 */ 251 uint32_t nrfx_atomic_flag_set(nrfx_atomic_flag_t * p_data); 252 253 /** 254 * @brief Function for running a logical one bit flag clear operation 255 * on an atomic object and returning its previous value. 256 * 257 * @param[in] p_data Atomic flag memory pointer. 258 * 259 * @return Previous flag value. 260 */ 261 uint32_t nrfx_atomic_flag_clear_fetch(nrfx_atomic_flag_t * p_data); 262 263 /** 264 * @brief Function for running a logical one bit flag clear operation 265 * on an atomic object and returning its new value. 266 * 267 * @param[in] p_data Atomic flag memory pointer. 268 * 269 * @return New flag value. 270 */ 271 uint32_t nrfx_atomic_flag_clear(nrfx_atomic_flag_t * p_data); 272 273 /** @} */ 274 275 #ifdef __cplusplus 276 } 277 #endif 278 279 #endif // NRFX_ATOMIC_H__ 280