Add volatile qualifiers to atomic functions

The atomic functions preserve volatile semantics - they only perform the
accesses specified. Add the volatile qualifier to the value pointer to
reflect this. This does not change existing caller code - it's
equivalent to adding a const qualifier to indicate we don't write to
a pointer - it means people can pass us qualified pointers without
casts, letting the compile check const- or volatile-correctness.

This is consistent with C11 <stdatomic.h>, which volatile-qualifies its
equivalent functions.

Note that this useage of volatile has nothing to do with the atomicity -
objects accessed via the atomic functions do not need to be volatile.
But it does permit these calls to be used on objects which have been
declared volatile.
pull/6461/head
Kevin Bracey 2017-11-28 12:45:50 +02:00 committed by adbridge
parent b7441114fd
commit c6ab7de915
2 changed files with 36 additions and 36 deletions

View File

@ -116,7 +116,7 @@ void core_util_critical_section_exit(void)
#pragma diag_suppress 3731 #pragma diag_suppress 3731
#endif #endif
bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
{ {
do { do {
uint8_t currentValue = __LDREXB(ptr); uint8_t currentValue = __LDREXB(ptr);
@ -129,7 +129,7 @@ bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_
return true; return true;
} }
bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
{ {
do { do {
uint16_t currentValue = __LDREXH(ptr); uint16_t currentValue = __LDREXH(ptr);
@ -143,7 +143,7 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
} }
bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
{ {
do { do {
uint32_t currentValue = __LDREXW(ptr); uint32_t currentValue = __LDREXW(ptr);
@ -156,7 +156,7 @@ bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uin
return true; return true;
} }
uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta) uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta)
{ {
uint8_t newValue; uint8_t newValue;
do { do {
@ -165,7 +165,7 @@ uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
return newValue; return newValue;
} }
uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta) uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta)
{ {
uint16_t newValue; uint16_t newValue;
do { do {
@ -174,7 +174,7 @@ uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
return newValue; return newValue;
} }
uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta) uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta)
{ {
uint32_t newValue; uint32_t newValue;
do { do {
@ -184,7 +184,7 @@ uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
} }
uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta) uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta)
{ {
uint8_t newValue; uint8_t newValue;
do { do {
@ -193,7 +193,7 @@ uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
return newValue; return newValue;
} }
uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta) uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta)
{ {
uint16_t newValue; uint16_t newValue;
do { do {
@ -202,7 +202,7 @@ uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
return newValue; return newValue;
} }
uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta) uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta)
{ {
uint32_t newValue; uint32_t newValue;
do { do {
@ -213,7 +213,7 @@ uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
#else #else
bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue) bool core_util_atomic_cas_u8(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
{ {
bool success; bool success;
uint8_t currentValue; uint8_t currentValue;
@ -230,7 +230,7 @@ bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_
return success; return success;
} }
bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue) bool core_util_atomic_cas_u16(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
{ {
bool success; bool success;
uint16_t currentValue; uint16_t currentValue;
@ -248,7 +248,7 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
} }
bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue) bool core_util_atomic_cas_u32(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
{ {
bool success; bool success;
uint32_t currentValue; uint32_t currentValue;
@ -266,7 +266,7 @@ bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uin
} }
uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta) uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta)
{ {
uint8_t newValue; uint8_t newValue;
core_util_critical_section_enter(); core_util_critical_section_enter();
@ -276,7 +276,7 @@ uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
return newValue; return newValue;
} }
uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta) uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta)
{ {
uint16_t newValue; uint16_t newValue;
core_util_critical_section_enter(); core_util_critical_section_enter();
@ -286,7 +286,7 @@ uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
return newValue; return newValue;
} }
uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta) uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta)
{ {
uint32_t newValue; uint32_t newValue;
core_util_critical_section_enter(); core_util_critical_section_enter();
@ -297,7 +297,7 @@ uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
} }
uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta) uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta)
{ {
uint8_t newValue; uint8_t newValue;
core_util_critical_section_enter(); core_util_critical_section_enter();
@ -307,7 +307,7 @@ uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
return newValue; return newValue;
} }
uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta) uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta)
{ {
uint16_t newValue; uint16_t newValue;
core_util_critical_section_enter(); core_util_critical_section_enter();
@ -317,7 +317,7 @@ uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
return newValue; return newValue;
} }
uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta) uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta)
{ {
uint32_t newValue; uint32_t newValue;
core_util_critical_section_enter(); core_util_critical_section_enter();
@ -330,18 +330,18 @@ uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
#endif #endif
bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue) { bool core_util_atomic_cas_ptr(void * volatile *ptr, void **expectedCurrentValue, void *desiredValue) {
return core_util_atomic_cas_u32( return core_util_atomic_cas_u32(
(uint32_t *)ptr, (volatile uint32_t *)ptr,
(uint32_t *)expectedCurrentValue, (uint32_t *)expectedCurrentValue,
(uint32_t)desiredValue); (uint32_t)desiredValue);
} }
void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta) { void *core_util_atomic_incr_ptr(void * volatile *valuePtr, ptrdiff_t delta) {
return (void *)core_util_atomic_incr_u32((uint32_t *)valuePtr, (uint32_t)delta); return (void *)core_util_atomic_incr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta);
} }
void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta) { void *core_util_atomic_decr_ptr(void * volatile *valuePtr, ptrdiff_t delta) {
return (void *)core_util_atomic_decr_u32((uint32_t *)valuePtr, (uint32_t)delta); return (void *)core_util_atomic_decr_u32((volatile uint32_t *)valuePtr, (uint32_t)delta);
} }

View File

@ -144,7 +144,7 @@ bool core_util_in_critical_section(void);
* always succeeds if the current value is expected, as per the pseudocode * always succeeds if the current value is expected, as per the pseudocode
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may. * 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(volatile uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue);
/** /**
* Atomic compare and set. It compares the contents of a memory location to a * Atomic compare and set. It compares the contents of a memory location to a
@ -201,7 +201,7 @@ bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_
* always succeeds if the current value is expected, as per the pseudocode * always succeeds if the current value is expected, as per the pseudocode
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may. * 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(volatile uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue);
/** /**
* Atomic compare and set. It compares the contents of a memory location to a * Atomic compare and set. It compares the contents of a memory location to a
@ -258,7 +258,7 @@ bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uin
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may. * 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(volatile uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue);
/** /**
* Atomic compare and set. It compares the contents of a memory location to a * Atomic compare and set. It compares the contents of a memory location to a
@ -315,7 +315,7 @@ bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uin
* always succeeds if the current value is expected, as per the pseudocode * always succeeds if the current value is expected, as per the pseudocode
* above; it will not spuriously fail as "atomic_compare_exchange_weak" may. * 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 * volatile *ptr, void **expectedCurrentValue, void *desiredValue);
/** /**
* Atomic increment. * Atomic increment.
@ -323,7 +323,7 @@ bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *des
* @param delta The amount being incremented. * @param delta The amount being incremented.
* @return The new incremented value. * @return The new incremented value.
*/ */
uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta); uint8_t core_util_atomic_incr_u8(volatile uint8_t *valuePtr, uint8_t delta);
/** /**
* Atomic increment. * Atomic increment.
@ -331,7 +331,7 @@ uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta);
* @param delta The amount being incremented. * @param delta The amount being incremented.
* @return The new incremented value. * @return The new incremented value.
*/ */
uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta); uint16_t core_util_atomic_incr_u16(volatile uint16_t *valuePtr, uint16_t delta);
/** /**
* Atomic increment. * Atomic increment.
@ -339,7 +339,7 @@ uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta);
* @param delta The amount being incremented. * @param delta The amount being incremented.
* @return The new incremented value. * @return The new incremented value.
*/ */
uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta); uint32_t core_util_atomic_incr_u32(volatile uint32_t *valuePtr, uint32_t delta);
/** /**
* Atomic increment. * Atomic increment.
@ -350,7 +350,7 @@ uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta);
* @note The type of the pointer argument is not taken into account * @note The type of the pointer argument is not taken into account
* and the pointer is incremented by bytes. * and the pointer is incremented by bytes.
*/ */
void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta); void *core_util_atomic_incr_ptr(void * volatile *valuePtr, ptrdiff_t delta);
/** /**
* Atomic decrement. * Atomic decrement.
@ -358,7 +358,7 @@ void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta);
* @param delta The amount being decremented. * @param delta The amount being decremented.
* @return The new decremented value. * @return The new decremented value.
*/ */
uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta); uint8_t core_util_atomic_decr_u8(volatile uint8_t *valuePtr, uint8_t delta);
/** /**
* Atomic decrement. * Atomic decrement.
@ -366,7 +366,7 @@ uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta);
* @param delta The amount being decremented. * @param delta The amount being decremented.
* @return The new decremented value. * @return The new decremented value.
*/ */
uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta); uint16_t core_util_atomic_decr_u16(volatile uint16_t *valuePtr, uint16_t delta);
/** /**
* Atomic decrement. * Atomic decrement.
@ -374,7 +374,7 @@ uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta);
* @param delta The amount being decremented. * @param delta The amount being decremented.
* @return The new decremented value. * @return The new decremented value.
*/ */
uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta); uint32_t core_util_atomic_decr_u32(volatile uint32_t *valuePtr, uint32_t delta);
/** /**
* Atomic decrement. * Atomic decrement.
@ -385,7 +385,7 @@ uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta);
* @note The type of the pointer argument is not taken into account * @note The type of the pointer argument is not taken into account
* and the pointer is decremented by bytes * and the pointer is decremented by bytes
*/ */
void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta); void *core_util_atomic_decr_ptr(void * volatile *valuePtr, ptrdiff_t delta);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"