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