This fork captures the mbed lib v125 for ease of integration into older projects.

Fork of mbed-dev by mbed official

Committer:
apluscw
Date:
Fri Jul 20 21:24:42 2018 +0000
Revision:
187:92cbb9eec47b
Parent:
144:ef7eb2e8f9f7
Child:
147:30b64687e01f
Mbed library with source code from mbed lib v125. Posted to ease integration with some older projects.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
<> 144:ef7eb2e8f9f7 3 * SPDX-License-Identifier: Apache-2.0
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
<> 144:ef7eb2e8f9f7 6 * not use this file except in compliance with the License.
<> 144:ef7eb2e8f9f7 7 * You may obtain a copy of the License at
<> 144:ef7eb2e8f9f7 8 *
<> 144:ef7eb2e8f9f7 9 * http://www.apache.org/licenses/LICENSE-2.0
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * Unless required by applicable law or agreed to in writing, software
<> 144:ef7eb2e8f9f7 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
<> 144:ef7eb2e8f9f7 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 144:ef7eb2e8f9f7 14 * See the License for the specific language governing permissions and
<> 144:ef7eb2e8f9f7 15 * limitations under the License.
<> 144:ef7eb2e8f9f7 16 */
<> 144:ef7eb2e8f9f7 17
<> 144:ef7eb2e8f9f7 18 #include "critical.h"
<> 144:ef7eb2e8f9f7 19
<> 144:ef7eb2e8f9f7 20 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 21 #include "mbed_assert.h"
<> 144:ef7eb2e8f9f7 22
<> 144:ef7eb2e8f9f7 23 #define EXCLUSIVE_ACCESS (!defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS))
<> 144:ef7eb2e8f9f7 24
<> 144:ef7eb2e8f9f7 25 static volatile uint32_t interrupt_enable_counter = 0;
<> 144:ef7eb2e8f9f7 26 static volatile bool critical_interrupts_disabled = false;
<> 144:ef7eb2e8f9f7 27
<> 144:ef7eb2e8f9f7 28 bool core_util_are_interrupts_enabled(void)
<> 144:ef7eb2e8f9f7 29 {
<> 144:ef7eb2e8f9f7 30 #if defined(__CORTEX_A9)
<> 144:ef7eb2e8f9f7 31 return ((__get_CPSR() & 0x80) == 0);
<> 144:ef7eb2e8f9f7 32 #else
<> 144:ef7eb2e8f9f7 33 return ((__get_PRIMASK() & 0x1) == 0);
<> 144:ef7eb2e8f9f7 34 #endif
<> 144:ef7eb2e8f9f7 35 }
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 void core_util_critical_section_enter(void)
<> 144:ef7eb2e8f9f7 38 {
<> 144:ef7eb2e8f9f7 39 bool interrupts_disabled = !core_util_are_interrupts_enabled();
<> 144:ef7eb2e8f9f7 40 __disable_irq();
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 /* Save the interrupt disabled state as it was prior to any nested critical section lock use */
<> 144:ef7eb2e8f9f7 43 if (!interrupt_enable_counter) {
<> 144:ef7eb2e8f9f7 44 critical_interrupts_disabled = interrupts_disabled;
<> 144:ef7eb2e8f9f7 45 }
<> 144:ef7eb2e8f9f7 46
<> 144:ef7eb2e8f9f7 47 /* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts
<> 144:ef7eb2e8f9f7 48 are enabled, then something has gone badly wrong thus assert an error.
<> 144:ef7eb2e8f9f7 49 */
<> 144:ef7eb2e8f9f7 50 MBED_ASSERT(interrupt_enable_counter < UINT32_MAX);
<> 144:ef7eb2e8f9f7 51 // FIXME
<> 144:ef7eb2e8f9f7 52 #ifndef FEATURE_UVISOR
<> 144:ef7eb2e8f9f7 53 if (interrupt_enable_counter > 0) {
<> 144:ef7eb2e8f9f7 54 MBED_ASSERT(interrupts_disabled);
<> 144:ef7eb2e8f9f7 55 }
<> 144:ef7eb2e8f9f7 56 #else
<> 144:ef7eb2e8f9f7 57 #warning "core_util_critical_section_enter needs fixing to work from unprivileged code"
<> 144:ef7eb2e8f9f7 58 #endif /* FEATURE_UVISOR */
<> 144:ef7eb2e8f9f7 59 interrupt_enable_counter++;
<> 144:ef7eb2e8f9f7 60 }
<> 144:ef7eb2e8f9f7 61
<> 144:ef7eb2e8f9f7 62 void core_util_critical_section_exit(void)
<> 144:ef7eb2e8f9f7 63 {
<> 144:ef7eb2e8f9f7 64 /* If critical_section_enter has not previously been called, do nothing */
<> 144:ef7eb2e8f9f7 65 if (interrupt_enable_counter) {
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 // FIXME
<> 144:ef7eb2e8f9f7 68 #ifndef FEATURE_UVISOR
<> 144:ef7eb2e8f9f7 69 bool interrupts_disabled = !core_util_are_interrupts_enabled(); /* get the current interrupt disabled state */
<> 144:ef7eb2e8f9f7 70
<> 144:ef7eb2e8f9f7 71 MBED_ASSERT(interrupts_disabled); /* Interrupts must be disabled on invoking an exit from a critical section */
<> 144:ef7eb2e8f9f7 72 #else
<> 144:ef7eb2e8f9f7 73 #warning "core_util_critical_section_exit needs fixing to work from unprivileged code"
<> 144:ef7eb2e8f9f7 74 #endif /* FEATURE_UVISOR */
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 interrupt_enable_counter--;
<> 144:ef7eb2e8f9f7 77
<> 144:ef7eb2e8f9f7 78 /* Only re-enable interrupts if we are exiting the last of the nested critical sections and
<> 144:ef7eb2e8f9f7 79 interrupts were enabled on entry to the first critical section.
<> 144:ef7eb2e8f9f7 80 */
<> 144:ef7eb2e8f9f7 81 if (!interrupt_enable_counter && !critical_interrupts_disabled) {
<> 144:ef7eb2e8f9f7 82 __enable_irq();
<> 144:ef7eb2e8f9f7 83 }
<> 144:ef7eb2e8f9f7 84 }
<> 144:ef7eb2e8f9f7 85 }
<> 144:ef7eb2e8f9f7 86
<> 144:ef7eb2e8f9f7 87 #if EXCLUSIVE_ACCESS
<> 144:ef7eb2e8f9f7 88
<> 144:ef7eb2e8f9f7 89 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
<> 144:ef7eb2e8f9f7 90 {
<> 144:ef7eb2e8f9f7 91 uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr);
<> 144:ef7eb2e8f9f7 92 if (currentValue != *expectedCurrentValue) {
<> 144:ef7eb2e8f9f7 93 *expectedCurrentValue = currentValue;
<> 144:ef7eb2e8f9f7 94 __CLREX();
<> 144:ef7eb2e8f9f7 95 return false;
<> 144:ef7eb2e8f9f7 96 }
<> 144:ef7eb2e8f9f7 97
<> 144:ef7eb2e8f9f7 98 return !__STREXB(desiredValue, (volatile uint8_t*)ptr);
<> 144:ef7eb2e8f9f7 99 }
<> 144:ef7eb2e8f9f7 100
<> 144:ef7eb2e8f9f7 101 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
<> 144:ef7eb2e8f9f7 102 {
<> 144:ef7eb2e8f9f7 103 uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr);
<> 144:ef7eb2e8f9f7 104 if (currentValue != *expectedCurrentValue) {
<> 144:ef7eb2e8f9f7 105 *expectedCurrentValue = currentValue;
<> 144:ef7eb2e8f9f7 106 __CLREX();
<> 144:ef7eb2e8f9f7 107 return false;
<> 144:ef7eb2e8f9f7 108 }
<> 144:ef7eb2e8f9f7 109
<> 144:ef7eb2e8f9f7 110 return !__STREXH(desiredValue, (volatile uint16_t*)ptr);
<> 144:ef7eb2e8f9f7 111 }
<> 144:ef7eb2e8f9f7 112
<> 144:ef7eb2e8f9f7 113
<> 144:ef7eb2e8f9f7 114 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
<> 144:ef7eb2e8f9f7 115 {
<> 144:ef7eb2e8f9f7 116 uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr);
<> 144:ef7eb2e8f9f7 117 if (currentValue != *expectedCurrentValue) {
<> 144:ef7eb2e8f9f7 118 *expectedCurrentValue = currentValue;
<> 144:ef7eb2e8f9f7 119 __CLREX();
<> 144:ef7eb2e8f9f7 120 return false;
<> 144:ef7eb2e8f9f7 121 }
<> 144:ef7eb2e8f9f7 122
<> 144:ef7eb2e8f9f7 123 return !__STREXW(desiredValue, (volatile uint32_t*)ptr);
<> 144:ef7eb2e8f9f7 124 }
<> 144:ef7eb2e8f9f7 125
<> 144:ef7eb2e8f9f7 126 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
<> 144:ef7eb2e8f9f7 127 {
<> 144:ef7eb2e8f9f7 128 uint8_t newValue;
<> 144:ef7eb2e8f9f7 129 do {
<> 144:ef7eb2e8f9f7 130 newValue = __LDREXB((volatile uint8_t*)valuePtr) + delta;
<> 144:ef7eb2e8f9f7 131 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));
<> 144:ef7eb2e8f9f7 132 return newValue;
<> 144:ef7eb2e8f9f7 133 }
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
<> 144:ef7eb2e8f9f7 136 {
<> 144:ef7eb2e8f9f7 137 uint16_t newValue;
<> 144:ef7eb2e8f9f7 138 do {
<> 144:ef7eb2e8f9f7 139 newValue = __LDREXH((volatile uint16_t*)valuePtr) + delta;
<> 144:ef7eb2e8f9f7 140 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));
<> 144:ef7eb2e8f9f7 141 return newValue;
<> 144:ef7eb2e8f9f7 142 }
<> 144:ef7eb2e8f9f7 143
<> 144:ef7eb2e8f9f7 144 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
<> 144:ef7eb2e8f9f7 145 {
<> 144:ef7eb2e8f9f7 146 uint32_t newValue;
<> 144:ef7eb2e8f9f7 147 do {
<> 144:ef7eb2e8f9f7 148 newValue = __LDREXW((volatile uint32_t*)valuePtr) + delta;
<> 144:ef7eb2e8f9f7 149 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));
<> 144:ef7eb2e8f9f7 150 return newValue;
<> 144:ef7eb2e8f9f7 151 }
<> 144:ef7eb2e8f9f7 152
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
<> 144:ef7eb2e8f9f7 155 {
<> 144:ef7eb2e8f9f7 156 uint8_t newValue;
<> 144:ef7eb2e8f9f7 157 do {
<> 144:ef7eb2e8f9f7 158 newValue = __LDREXB((volatile uint8_t*)valuePtr) - delta;
<> 144:ef7eb2e8f9f7 159 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));
<> 144:ef7eb2e8f9f7 160 return newValue;
<> 144:ef7eb2e8f9f7 161 }
<> 144:ef7eb2e8f9f7 162
<> 144:ef7eb2e8f9f7 163 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
<> 144:ef7eb2e8f9f7 164 {
<> 144:ef7eb2e8f9f7 165 uint16_t newValue;
<> 144:ef7eb2e8f9f7 166 do {
<> 144:ef7eb2e8f9f7 167 newValue = __LDREXH((volatile uint16_t*)valuePtr) - delta;
<> 144:ef7eb2e8f9f7 168 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));
<> 144:ef7eb2e8f9f7 169 return newValue;
<> 144:ef7eb2e8f9f7 170 }
<> 144:ef7eb2e8f9f7 171
<> 144:ef7eb2e8f9f7 172 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
<> 144:ef7eb2e8f9f7 173 {
<> 144:ef7eb2e8f9f7 174 uint32_t newValue;
<> 144:ef7eb2e8f9f7 175 do {
<> 144:ef7eb2e8f9f7 176 newValue = __LDREXW((volatile uint32_t*)valuePtr) - delta;
<> 144:ef7eb2e8f9f7 177 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));
<> 144:ef7eb2e8f9f7 178 return newValue;
<> 144:ef7eb2e8f9f7 179 }
<> 144:ef7eb2e8f9f7 180
<> 144:ef7eb2e8f9f7 181 #else
<> 144:ef7eb2e8f9f7 182
<> 144:ef7eb2e8f9f7 183 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
<> 144:ef7eb2e8f9f7 184 {
<> 144:ef7eb2e8f9f7 185 bool success;
<> 144:ef7eb2e8f9f7 186 uint8_t currentValue;
<> 144:ef7eb2e8f9f7 187 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 188 currentValue = *ptr;
<> 144:ef7eb2e8f9f7 189 if (currentValue == *expectedCurrentValue) {
<> 144:ef7eb2e8f9f7 190 *ptr = desiredValue;
<> 144:ef7eb2e8f9f7 191 success = true;
<> 144:ef7eb2e8f9f7 192 } else {
<> 144:ef7eb2e8f9f7 193 *expectedCurrentValue = currentValue;
<> 144:ef7eb2e8f9f7 194 success = false;
<> 144:ef7eb2e8f9f7 195 }
<> 144:ef7eb2e8f9f7 196 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 197 return success;
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199
<> 144:ef7eb2e8f9f7 200 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
<> 144:ef7eb2e8f9f7 201 {
<> 144:ef7eb2e8f9f7 202 bool success;
<> 144:ef7eb2e8f9f7 203 uint16_t currentValue;
<> 144:ef7eb2e8f9f7 204 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 205 currentValue = *ptr;
<> 144:ef7eb2e8f9f7 206 if (currentValue == *expectedCurrentValue) {
<> 144:ef7eb2e8f9f7 207 *ptr = desiredValue;
<> 144:ef7eb2e8f9f7 208 success = true;
<> 144:ef7eb2e8f9f7 209 } else {
<> 144:ef7eb2e8f9f7 210 *expectedCurrentValue = currentValue;
<> 144:ef7eb2e8f9f7 211 success = false;
<> 144:ef7eb2e8f9f7 212 }
<> 144:ef7eb2e8f9f7 213 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 214 return success;
<> 144:ef7eb2e8f9f7 215 }
<> 144:ef7eb2e8f9f7 216
<> 144:ef7eb2e8f9f7 217
<> 144:ef7eb2e8f9f7 218 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
<> 144:ef7eb2e8f9f7 219 {
<> 144:ef7eb2e8f9f7 220 bool success;
<> 144:ef7eb2e8f9f7 221 uint32_t currentValue;
<> 144:ef7eb2e8f9f7 222 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 223 currentValue = *ptr;
<> 144:ef7eb2e8f9f7 224 if (currentValue == *expectedCurrentValue) {
<> 144:ef7eb2e8f9f7 225 *ptr = desiredValue;
<> 144:ef7eb2e8f9f7 226 success = true;
<> 144:ef7eb2e8f9f7 227 } else {
<> 144:ef7eb2e8f9f7 228 *expectedCurrentValue = currentValue;
<> 144:ef7eb2e8f9f7 229 success = false;
<> 144:ef7eb2e8f9f7 230 }
<> 144:ef7eb2e8f9f7 231 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 232 return success;
<> 144:ef7eb2e8f9f7 233 }
<> 144:ef7eb2e8f9f7 234
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
<> 144:ef7eb2e8f9f7 237 {
<> 144:ef7eb2e8f9f7 238 uint8_t newValue;
<> 144:ef7eb2e8f9f7 239 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 240 newValue = *valuePtr + delta;
<> 144:ef7eb2e8f9f7 241 *valuePtr = newValue;
<> 144:ef7eb2e8f9f7 242 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 243 return newValue;
<> 144:ef7eb2e8f9f7 244 }
<> 144:ef7eb2e8f9f7 245
<> 144:ef7eb2e8f9f7 246 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
<> 144:ef7eb2e8f9f7 247 {
<> 144:ef7eb2e8f9f7 248 uint16_t newValue;
<> 144:ef7eb2e8f9f7 249 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 250 newValue = *valuePtr + delta;
<> 144:ef7eb2e8f9f7 251 *valuePtr = newValue;
<> 144:ef7eb2e8f9f7 252 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 253 return newValue;
<> 144:ef7eb2e8f9f7 254 }
<> 144:ef7eb2e8f9f7 255
<> 144:ef7eb2e8f9f7 256 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
<> 144:ef7eb2e8f9f7 257 {
<> 144:ef7eb2e8f9f7 258 uint32_t newValue;
<> 144:ef7eb2e8f9f7 259 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 260 newValue = *valuePtr + delta;
<> 144:ef7eb2e8f9f7 261 *valuePtr = newValue;
<> 144:ef7eb2e8f9f7 262 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 263 return newValue;
<> 144:ef7eb2e8f9f7 264 }
<> 144:ef7eb2e8f9f7 265
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
<> 144:ef7eb2e8f9f7 268 {
<> 144:ef7eb2e8f9f7 269 uint8_t newValue;
<> 144:ef7eb2e8f9f7 270 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 271 newValue = *valuePtr - delta;
<> 144:ef7eb2e8f9f7 272 *valuePtr = newValue;
<> 144:ef7eb2e8f9f7 273 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 274 return newValue;
<> 144:ef7eb2e8f9f7 275 }
<> 144:ef7eb2e8f9f7 276
<> 144:ef7eb2e8f9f7 277 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
<> 144:ef7eb2e8f9f7 278 {
<> 144:ef7eb2e8f9f7 279 uint16_t newValue;
<> 144:ef7eb2e8f9f7 280 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 281 newValue = *valuePtr - delta;
<> 144:ef7eb2e8f9f7 282 *valuePtr = newValue;
<> 144:ef7eb2e8f9f7 283 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 284 return newValue;
<> 144:ef7eb2e8f9f7 285 }
<> 144:ef7eb2e8f9f7 286
<> 144:ef7eb2e8f9f7 287 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
<> 144:ef7eb2e8f9f7 288 {
<> 144:ef7eb2e8f9f7 289 uint32_t newValue;
<> 144:ef7eb2e8f9f7 290 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 291 newValue = *valuePtr - delta;
<> 144:ef7eb2e8f9f7 292 *valuePtr = newValue;
<> 144:ef7eb2e8f9f7 293 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 294 return newValue;
<> 144:ef7eb2e8f9f7 295 }
<> 144:ef7eb2e8f9f7 296
<> 144:ef7eb2e8f9f7 297 #endif
<> 144:ef7eb2e8f9f7 298
<> 144:ef7eb2e8f9f7 299
<> 144:ef7eb2e8f9f7 300 bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue) {
<> 144:ef7eb2e8f9f7 301 return core_util_atomic_cas_u32(
<> 144:ef7eb2e8f9f7 302 (uint32_t *)ptr,
<> 144:ef7eb2e8f9f7 303 (uint32_t *)expectedCurrentValue,
<> 144:ef7eb2e8f9f7 304 (uint32_t)desiredValue);
<> 144:ef7eb2e8f9f7 305 }
<> 144:ef7eb2e8f9f7 306
<> 144:ef7eb2e8f9f7 307 void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta) {
<> 144:ef7eb2e8f9f7 308 return (void *)core_util_atomic_incr_u32((uint32_t *)valuePtr, (uint32_t)delta);
<> 144:ef7eb2e8f9f7 309 }
<> 144:ef7eb2e8f9f7 310
<> 144:ef7eb2e8f9f7 311 void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta) {
<> 144:ef7eb2e8f9f7 312 return (void *)core_util_atomic_decr_u32((uint32_t *)valuePtr, (uint32_t)delta);
<> 144:ef7eb2e8f9f7 313 }
<> 144:ef7eb2e8f9f7 314