mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #5596 from kjbracey-arm/strong_cas
Make LDREX/STREX CAS functions strongpull/5586/merge
commit
b076565ac0
|
@ -110,39 +110,42 @@ MBED_WEAK void core_util_critical_section_exit(void)
|
||||||
|
|
||||||
bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
|
bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
|
||||||
{
|
{
|
||||||
uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr);
|
do {
|
||||||
if (currentValue != *expectedCurrentValue) {
|
uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr);
|
||||||
*expectedCurrentValue = currentValue;
|
if (currentValue != *expectedCurrentValue) {
|
||||||
__CLREX();
|
*expectedCurrentValue = currentValue;
|
||||||
return false;
|
__CLREX();
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
return !__STREXB(desiredValue, (volatile uint8_t*)ptr);
|
} while (__STREXB(desiredValue, (volatile uint8_t*)ptr));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
|
bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
|
||||||
{
|
{
|
||||||
uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr);
|
do {
|
||||||
if (currentValue != *expectedCurrentValue) {
|
uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr);
|
||||||
*expectedCurrentValue = currentValue;
|
if (currentValue != *expectedCurrentValue) {
|
||||||
__CLREX();
|
*expectedCurrentValue = currentValue;
|
||||||
return false;
|
__CLREX();
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
return !__STREXH(desiredValue, (volatile uint16_t*)ptr);
|
} while (__STREXH(desiredValue, (volatile uint16_t*)ptr));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
|
bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
|
||||||
{
|
{
|
||||||
uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr);
|
do {
|
||||||
if (currentValue != *expectedCurrentValue) {
|
uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr);
|
||||||
*expectedCurrentValue = currentValue;
|
if (currentValue != *expectedCurrentValue) {
|
||||||
__CLREX();
|
*expectedCurrentValue = currentValue;
|
||||||
return false;
|
__CLREX();
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
return !__STREXW(desiredValue, (volatile uint32_t*)ptr);
|
} while (__STREXW(desiredValue, (volatile uint32_t*)ptr));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
|
uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
|
||||||
|
|
|
@ -121,7 +121,7 @@ void core_util_critical_section_exit(void);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @note: In the failure case (where the destination isn't set), the value
|
* @note: In the failure case (where the destination isn't set), the value
|
||||||
* pointed to by expectedCurrentValue is still updated with the current value.
|
* pointed to by expectedCurrentValue is instead updated with the current value.
|
||||||
* This property helps writing concise code for the following incr:
|
* This property helps writing concise code for the following incr:
|
||||||
*
|
*
|
||||||
* function incr(p : pointer to int, a : int) returns int {
|
* function incr(p : pointer to int, a : int) returns int {
|
||||||
|
@ -132,6 +132,10 @@ void core_util_critical_section_exit(void);
|
||||||
* }
|
* }
|
||||||
* return value + a
|
* return value + a
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* @note: This corresponds to the C11 "atomic_compare_exchange_strong" - it
|
||||||
|
* always succeeds if the current value is expected, as per the pseudocode
|
||||||
|
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may.
|
||||||
*/
|
*/
|
||||||
bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue);
|
bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue);
|
||||||
|
|
||||||
|
@ -174,7 +178,7 @@ bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @note: In the failure case (where the destination isn't set), the value
|
* @note: In the failure case (where the destination isn't set), the value
|
||||||
* pointed to by expectedCurrentValue is still updated with the current value.
|
* pointed to by expectedCurrentValue is instead updated with the current value.
|
||||||
* This property helps writing concise code for the following incr:
|
* This property helps writing concise code for the following incr:
|
||||||
*
|
*
|
||||||
* function incr(p : pointer to int, a : int) returns int {
|
* function incr(p : pointer to int, a : int) returns int {
|
||||||
|
@ -185,6 +189,10 @@ bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_
|
||||||
* }
|
* }
|
||||||
* return value + a
|
* return value + a
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* @note: This corresponds to the C11 "atomic_compare_exchange_strong" - it
|
||||||
|
* always succeeds if the current value is expected, as per the pseudocode
|
||||||
|
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may.
|
||||||
*/
|
*/
|
||||||
bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue);
|
bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue);
|
||||||
|
|
||||||
|
@ -227,7 +235,7 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @note: In the failure case (where the destination isn't set), the value
|
* @note: In the failure case (where the destination isn't set), the value
|
||||||
* pointed to by expectedCurrentValue is still updated with the current value.
|
* pointed to by expectedCurrentValue is instead updated with the current value.
|
||||||
* This property helps writing concise code for the following incr:
|
* This property helps writing concise code for the following incr:
|
||||||
*
|
*
|
||||||
* function incr(p : pointer to int, a : int) returns int {
|
* function incr(p : pointer to int, a : int) returns int {
|
||||||
|
@ -237,6 +245,10 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
|
||||||
* done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
|
* done = atomic_cas(p, &value, value + a) // *value gets updated automatically until success
|
||||||
* }
|
* }
|
||||||
* return value + a
|
* return value + a
|
||||||
|
*
|
||||||
|
* @note: This corresponds to the C11 "atomic_compare_exchange_strong" - it
|
||||||
|
* always succeeds if the current value is expected, as per the pseudocode
|
||||||
|
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may.
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue);
|
bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue);
|
||||||
|
@ -280,7 +292,7 @@ bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uin
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @note: In the failure case (where the destination isn't set), the value
|
* @note: In the failure case (where the destination isn't set), the value
|
||||||
* pointed to by expectedCurrentValue is still updated with the current value.
|
* pointed to by expectedCurrentValue is instead updated with the current value.
|
||||||
* This property helps writing concise code for the following incr:
|
* This property helps writing concise code for the following incr:
|
||||||
*
|
*
|
||||||
* function incr(p : pointer to int, a : int) returns int {
|
* function incr(p : pointer to int, a : int) returns int {
|
||||||
|
@ -291,6 +303,10 @@ bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uin
|
||||||
* }
|
* }
|
||||||
* return value + a
|
* return value + a
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
|
* @note: This corresponds to the C11 "atomic_compare_exchange_strong" - it
|
||||||
|
* always succeeds if the current value is expected, as per the pseudocode
|
||||||
|
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may.
|
||||||
*/
|
*/
|
||||||
bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue);
|
bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue