mbed library sources. Supersedes mbed-src.
Dependents: LPCXpresso1769_blinky
Fork of mbed-dev by
critical.h
00001 /* 00002 * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef __MBED_UTIL_CRITICAL_H__ 00019 #define __MBED_UTIL_CRITICAL_H__ 00020 00021 #include <stdbool.h> 00022 #include <stdint.h> 00023 #include <stddef.h> 00024 00025 #ifdef __cplusplus 00026 extern "C" { 00027 #endif 00028 00029 00030 /** Determine the current interrupts enabled state 00031 * 00032 * This function can be called to determine whether or not interrupts are currently enabled. 00033 * \note 00034 * NOTE: 00035 * This function works for both cortex-A and cortex-M, although the underlyng implementation 00036 * differs. 00037 * @return true if interrupts are enabled, false otherwise 00038 */ 00039 bool core_util_are_interrupts_enabled(void); 00040 00041 /** Mark the start of a critical section 00042 * 00043 * This function should be called to mark the start of a critical section of code. 00044 * \note 00045 * NOTES: 00046 * 1) The use of this style of critical section is targetted at C based implementations. 00047 * 2) These critical sections can be nested. 00048 * 3) The interrupt enable state on entry to the first critical section (of a nested set, or single 00049 * section) will be preserved on exit from the section. 00050 * 4) This implementation will currently only work on code running in privileged mode. 00051 */ 00052 void core_util_critical_section_enter(void); 00053 00054 /** Mark the end of a critical section 00055 * 00056 * This function should be called to mark the end of a critical section of code. 00057 * \note 00058 * NOTES: 00059 * 1) The use of this style of critical section is targetted at C based implementations. 00060 * 2) These critical sections can be nested. 00061 * 3) The interrupt enable state on entry to the first critical section (of a nested set, or single 00062 * section) will be preserved on exit from the section. 00063 * 4) This implementation will currently only work on code running in privileged mode. 00064 */ 00065 void core_util_critical_section_exit(void); 00066 00067 /** 00068 * Atomic compare and set. It compares the contents of a memory location to a 00069 * given value and, only if they are the same, modifies the contents of that 00070 * memory location to a given new value. This is done as a single atomic 00071 * operation. The atomicity guarantees that the new value is calculated based on 00072 * up-to-date information; if the value had been updated by another thread in 00073 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00074 * 00075 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00076 * you to the article on compare-and swap]. 00077 * 00078 * @param ptr The target memory location. 00079 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00080 * expected current value of the data being set atomically. 00081 * The computed 'desiredValue' should be a function of this current value. 00082 * @Note: This is an in-out parameter. In the 00083 * failure case of atomic_cas (where the 00084 * destination isn't set), the pointee of expectedCurrentValue is 00085 * updated with the current value. 00086 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00087 * 00088 * @return true if the memory location was atomically 00089 * updated with the desired value (after verifying 00090 * that it contained the expectedCurrentValue), 00091 * false otherwise. In the failure case, 00092 * exepctedCurrentValue is updated with the new 00093 * value of the target memory location. 00094 * 00095 * pseudocode: 00096 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00097 * if *p != *old { 00098 * *old = *p 00099 * return false 00100 * } 00101 * *p = new 00102 * return true 00103 * } 00104 * 00105 * @Note: In the failure case (where the destination isn't set), the value 00106 * pointed to by expectedCurrentValue is still updated with the current value. 00107 * This property helps writing concise code for the following incr: 00108 * 00109 * function incr(p : pointer to int, a : int) returns int { 00110 * done = false 00111 * value = *p // This fetch operation need not be atomic. 00112 * while not done { 00113 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00114 * } 00115 * return value + a 00116 * } 00117 */ 00118 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue); 00119 00120 /** 00121 * Atomic compare and set. It compares the contents of a memory location to a 00122 * given value and, only if they are the same, modifies the contents of that 00123 * memory location to a given new value. This is done as a single atomic 00124 * operation. The atomicity guarantees that the new value is calculated based on 00125 * up-to-date information; if the value had been updated by another thread in 00126 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00127 * 00128 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00129 * you to the article on compare-and swap]. 00130 * 00131 * @param ptr The target memory location. 00132 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00133 * expected current value of the data being set atomically. 00134 * The computed 'desiredValue' should be a function of this current value. 00135 * @Note: This is an in-out parameter. In the 00136 * failure case of atomic_cas (where the 00137 * destination isn't set), the pointee of expectedCurrentValue is 00138 * updated with the current value. 00139 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00140 * 00141 * @return true if the memory location was atomically 00142 * updated with the desired value (after verifying 00143 * that it contained the expectedCurrentValue), 00144 * false otherwise. In the failure case, 00145 * exepctedCurrentValue is updated with the new 00146 * value of the target memory location. 00147 * 00148 * pseudocode: 00149 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00150 * if *p != *old { 00151 * *old = *p 00152 * return false 00153 * } 00154 * *p = new 00155 * return true 00156 * } 00157 * 00158 * @Note: In the failure case (where the destination isn't set), the value 00159 * pointed to by expectedCurrentValue is still updated with the current value. 00160 * This property helps writing concise code for the following incr: 00161 * 00162 * function incr(p : pointer to int, a : int) returns int { 00163 * done = false 00164 * value = *p // This fetch operation need not be atomic. 00165 * while not done { 00166 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00167 * } 00168 * return value + a 00169 * } 00170 */ 00171 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue); 00172 00173 /** 00174 * Atomic compare and set. It compares the contents of a memory location to a 00175 * given value and, only if they are the same, modifies the contents of that 00176 * memory location to a given new value. This is done as a single atomic 00177 * operation. The atomicity guarantees that the new value is calculated based on 00178 * up-to-date information; if the value had been updated by another thread in 00179 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00180 * 00181 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00182 * you to the article on compare-and swap]. 00183 * 00184 * @param ptr The target memory location. 00185 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00186 * expected current value of the data being set atomically. 00187 * The computed 'desiredValue' should be a function of this current value. 00188 * @Note: This is an in-out parameter. In the 00189 * failure case of atomic_cas (where the 00190 * destination isn't set), the pointee of expectedCurrentValue is 00191 * updated with the current value. 00192 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00193 * 00194 * @return true if the memory location was atomically 00195 * updated with the desired value (after verifying 00196 * that it contained the expectedCurrentValue), 00197 * false otherwise. In the failure case, 00198 * exepctedCurrentValue is updated with the new 00199 * value of the target memory location. 00200 * 00201 * pseudocode: 00202 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00203 * if *p != *old { 00204 * *old = *p 00205 * return false 00206 * } 00207 * *p = new 00208 * return true 00209 * } 00210 * 00211 * @Note: In the failure case (where the destination isn't set), the value 00212 * pointed to by expectedCurrentValue is still updated with the current value. 00213 * This property helps writing concise code for the following incr: 00214 * 00215 * function incr(p : pointer to int, a : int) returns int { 00216 * done = false 00217 * value = *p // This fetch operation need not be atomic. 00218 * while not done { 00219 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00220 * } 00221 * return value + a 00222 * } 00223 */ 00224 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue); 00225 00226 /** 00227 * Atomic compare and set. It compares the contents of a memory location to a 00228 * given value and, only if they are the same, modifies the contents of that 00229 * memory location to a given new value. This is done as a single atomic 00230 * operation. The atomicity guarantees that the new value is calculated based on 00231 * up-to-date information; if the value had been updated by another thread in 00232 * the meantime, the write would fail due to a mismatched expectedCurrentValue. 00233 * 00234 * Refer to https://en.wikipedia.org/wiki/Compare-and-set [which may redirect 00235 * you to the article on compare-and swap]. 00236 * 00237 * @param ptr The target memory location. 00238 * @param[in,out] expectedCurrentValue A pointer to some location holding the 00239 * expected current value of the data being set atomically. 00240 * The computed 'desiredValue' should be a function of this current value. 00241 * @Note: This is an in-out parameter. In the 00242 * failure case of atomic_cas (where the 00243 * destination isn't set), the pointee of expectedCurrentValue is 00244 * updated with the current value. 00245 * @param[in] desiredValue The new value computed based on '*expectedCurrentValue'. 00246 * 00247 * @return true if the memory location was atomically 00248 * updated with the desired value (after verifying 00249 * that it contained the expectedCurrentValue), 00250 * false otherwise. In the failure case, 00251 * exepctedCurrentValue is updated with the new 00252 * value of the target memory location. 00253 * 00254 * pseudocode: 00255 * function cas(p : pointer to int, old : pointer to int, new : int) returns bool { 00256 * if *p != *old { 00257 * *old = *p 00258 * return false 00259 * } 00260 * *p = new 00261 * return true 00262 * } 00263 * 00264 * @Note: In the failure case (where the destination isn't set), the value 00265 * pointed to by expectedCurrentValue is still updated with the current value. 00266 * This property helps writing concise code for the following incr: 00267 * 00268 * function incr(p : pointer to int, a : int) returns int { 00269 * done = false 00270 * value = *p // This fetch operation need not be atomic. 00271 * while not done { 00272 * done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success 00273 * } 00274 * return value + a 00275 * } 00276 */ 00277 bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue); 00278 00279 /** 00280 * Atomic increment. 00281 * @param valuePtr Target memory location being incremented. 00282 * @param delta The amount being incremented. 00283 * @return The new incremented value. 00284 */ 00285 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta); 00286 00287 /** 00288 * Atomic increment. 00289 * @param valuePtr Target memory location being incremented. 00290 * @param delta The amount being incremented. 00291 * @return The new incremented value. 00292 */ 00293 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta); 00294 00295 /** 00296 * Atomic increment. 00297 * @param valuePtr Target memory location being incremented. 00298 * @param delta The amount being incremented. 00299 * @return The new incremented value. 00300 */ 00301 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta); 00302 00303 /** 00304 * Atomic increment. 00305 * @param valuePtr Target memory location being incremented. 00306 * @param delta The amount being incremented in bytes. 00307 * @return The new incremented value. 00308 * 00309 * @note The type of the pointer argument is not taken into account 00310 * and the pointer is incremented by bytes. 00311 */ 00312 void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta); 00313 00314 /** 00315 * Atomic decrement. 00316 * @param valuePtr Target memory location being decremented. 00317 * @param delta The amount being decremented. 00318 * @return The new decremented value. 00319 */ 00320 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta); 00321 00322 /** 00323 * Atomic decrement. 00324 * @param valuePtr Target memory location being decremented. 00325 * @param delta The amount being decremented. 00326 * @return The new decremented value. 00327 */ 00328 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta); 00329 00330 /** 00331 * Atomic decrement. 00332 * @param valuePtr Target memory location being decremented. 00333 * @param delta The amount being decremented. 00334 * @return The new decremented value. 00335 */ 00336 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta); 00337 00338 /** 00339 * Atomic decrement. 00340 * @param valuePtr Target memory location being decremented. 00341 * @param delta The amount being decremented in bytes. 00342 * @return The new decremented value. 00343 * 00344 * @note The type of the pointer argument is not taken into account 00345 * and the pointer is decremented by bytes 00346 */ 00347 void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta); 00348 00349 #ifdef __cplusplus 00350 } // extern "C" 00351 #endif 00352 00353 00354 #endif // __MBED_UTIL_CRITICAL_H__
Generated on Tue Jul 12 2022 16:04:25 by 1.7.2