kernel: atomic: consistently use named type for atomic pointer values
There's a typedef for non-pointer values compatible with atomic non-pointer objects. Add a similar typedef for pointer values, and the corresponding macro for initializing atomic pointer types. This also will simplify replacing the Zephyr atomic API with one based on C11 atomics, should that be desirable. C11 atomic pointer values are not void*. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
50cf28adb4
commit
f69a38162a
5 changed files with 44 additions and 29 deletions
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
typedef int atomic_t;
|
||||
typedef atomic_t atomic_val_t;
|
||||
typedef void *atomic_ptr_t;
|
||||
typedef atomic_ptr_t atomic_ptr_val_t;
|
||||
|
||||
/* Low-level primitives come in several styles: */
|
||||
|
||||
|
@ -56,6 +57,17 @@ typedef void *atomic_ptr_t;
|
|||
*/
|
||||
#define ATOMIC_INIT(i) (i)
|
||||
|
||||
/**
|
||||
* @brief Initialize an atomic pointer variable.
|
||||
*
|
||||
* This macro can be used to initialize an atomic pointer variable. For
|
||||
* example,
|
||||
* @code atomic_ptr_t my_ptr = ATOMIC_PTR_INIT(&data); @endcode
|
||||
*
|
||||
* @param p Pointer value to assign to atomic pointer variable.
|
||||
*/
|
||||
#define ATOMIC_PTR_INIT(p) (p)
|
||||
|
||||
/**
|
||||
* @cond INTERNAL_HIDDEN
|
||||
*/
|
||||
|
|
|
@ -55,8 +55,8 @@ static inline bool atomic_cas(atomic_t *target, atomic_val_t old_value,
|
|||
* @param new_value New value to store.
|
||||
* @return true if @a new_value is written, false otherwise.
|
||||
*/
|
||||
static inline bool atomic_ptr_cas(atomic_ptr_t *target, void *old_value,
|
||||
void *new_value)
|
||||
static inline bool atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value,
|
||||
atomic_ptr_val_t new_value)
|
||||
{
|
||||
return __atomic_compare_exchange_n(target, &old_value, new_value,
|
||||
0, __ATOMIC_SEQ_CST,
|
||||
|
@ -150,7 +150,7 @@ static inline atomic_val_t atomic_get(const atomic_t *target)
|
|||
*
|
||||
* @return Value of @a target.
|
||||
*/
|
||||
static inline void *atomic_ptr_get(const atomic_ptr_t *target)
|
||||
static inline atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target)
|
||||
{
|
||||
return __atomic_load_n(target, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
|
|||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline void *atomic_ptr_set(atomic_ptr_t *target, void *value)
|
||||
static inline atomic_ptr_val_t atomic_ptr_set(atomic_ptr_t *target, atomic_ptr_val_t value)
|
||||
{
|
||||
return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ static inline atomic_val_t atomic_clear(atomic_t *target)
|
|||
*
|
||||
* @return Previous value of @a target.
|
||||
*/
|
||||
static inline void *atomic_ptr_clear(atomic_ptr_t *target)
|
||||
static inline atomic_ptr_val_t atomic_ptr_clear(atomic_ptr_t *target)
|
||||
{
|
||||
return atomic_ptr_set(target, NULL);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ extern "C" {
|
|||
__syscall bool atomic_cas(atomic_t *target, atomic_val_t old_value,
|
||||
atomic_val_t new_value);
|
||||
|
||||
__syscall bool atomic_ptr_cas(atomic_ptr_t *target, void *old_value,
|
||||
void *new_value);
|
||||
__syscall bool atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value,
|
||||
atomic_ptr_val_t new_value);
|
||||
|
||||
__syscall atomic_val_t atomic_add(atomic_t *target, atomic_val_t value);
|
||||
|
||||
|
@ -41,11 +41,11 @@ static inline atomic_val_t atomic_dec(atomic_t *target)
|
|||
|
||||
extern atomic_val_t atomic_get(const atomic_t *target);
|
||||
|
||||
extern void *atomic_ptr_get(const atomic_ptr_t *target);
|
||||
extern atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target);
|
||||
|
||||
__syscall atomic_val_t atomic_set(atomic_t *target, atomic_val_t value);
|
||||
|
||||
__syscall void *atomic_ptr_set(atomic_ptr_t *target, void *value);
|
||||
__syscall atomic_ptr_val_t atomic_ptr_set(atomic_ptr_t *target, atomic_ptr_val_t value);
|
||||
|
||||
static inline atomic_val_t atomic_clear(atomic_t *target)
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ static inline atomic_val_t atomic_clear(atomic_t *target)
|
|||
|
||||
}
|
||||
|
||||
static inline void *atomic_ptr_clear(atomic_ptr_t *target)
|
||||
static inline atomic_ptr_val_t atomic_ptr_clear(atomic_ptr_t *target)
|
||||
{
|
||||
return atomic_ptr_set(target, NULL);
|
||||
|
||||
|
|
|
@ -107,8 +107,8 @@ bool z_vrfy_atomic_cas(atomic_t *target, atomic_val_t old_value,
|
|||
#include <syscalls/atomic_cas_mrsh.c>
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
bool z_impl_atomic_ptr_cas(atomic_ptr_t *target, void *old_value,
|
||||
void *new_value)
|
||||
bool z_impl_atomic_ptr_cas(atomic_ptr_t *target, atomic_ptr_val_t old_value,
|
||||
atomic_ptr_val_t new_value)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
int ret = false;
|
||||
|
@ -126,8 +126,9 @@ bool z_impl_atomic_ptr_cas(atomic_ptr_t *target, void *old_value,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
static inline bool z_vrfy_atomic_ptr_cas(atomic_ptr_t *target, void *old_value,
|
||||
void *new_value)
|
||||
static inline bool z_vrfy_atomic_ptr_cas(atomic_ptr_t *target,
|
||||
atomic_ptr_val_t old_value,
|
||||
atomic_ptr_val_t new_value)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t)));
|
||||
|
||||
|
@ -213,7 +214,7 @@ atomic_val_t atomic_get(const atomic_t *target)
|
|||
return *target;
|
||||
}
|
||||
|
||||
void *atomic_ptr_get(const atomic_ptr_t *target)
|
||||
atomic_ptr_val_t atomic_ptr_get(const atomic_ptr_t *target)
|
||||
{
|
||||
return *target;
|
||||
}
|
||||
|
@ -247,10 +248,11 @@ atomic_val_t z_impl_atomic_set(atomic_t *target, atomic_val_t value)
|
|||
|
||||
ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_set);
|
||||
|
||||
void *z_impl_atomic_ptr_set(atomic_ptr_t *target, void *value)
|
||||
atomic_ptr_val_t z_impl_atomic_ptr_set(atomic_ptr_t *target,
|
||||
atomic_ptr_val_t value)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
void *ret;
|
||||
atomic_ptr_val_t ret;
|
||||
|
||||
key = k_spin_lock(&lock);
|
||||
|
||||
|
@ -263,7 +265,8 @@ void *z_impl_atomic_ptr_set(atomic_ptr_t *target, void *value)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
static inline void *z_vrfy_atomic_ptr_set(atomic_ptr_t *target, void *value)
|
||||
static inline atomic_ptr_val_t z_vrfy_atomic_ptr_set(atomic_ptr_t *target,
|
||||
atomic_ptr_val_t value)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_ptr_t)));
|
||||
|
||||
|
|
|
@ -100,12 +100,12 @@ void test_atomic(void)
|
|||
zassert_true((target == value), "atomic_cas");
|
||||
|
||||
/* atomic_ptr_cas() */
|
||||
ptr_target = (atomic_ptr_t)4;
|
||||
ptr_value = (void *)5;
|
||||
old_ptr_value = (void *)6;
|
||||
ptr_target = ATOMIC_PTR_INIT((void *)4);
|
||||
ptr_value = (atomic_ptr_val_t)5;
|
||||
old_ptr_value = (atomic_ptr_val_t)6;
|
||||
zassert_false(atomic_ptr_cas(&ptr_target, old_ptr_value, ptr_value),
|
||||
"atomic_ptr_cas");
|
||||
ptr_target = (void *)6;
|
||||
ptr_target = (atomic_ptr_val_t)6;
|
||||
zassert_true(atomic_ptr_cas(&ptr_target, old_ptr_value, ptr_value),
|
||||
"atomic_ptr_cas");
|
||||
zassert_true((ptr_target == ptr_value), "atomic_ptr_cas");
|
||||
|
@ -147,8 +147,8 @@ void test_atomic(void)
|
|||
zassert_true((atomic_get(&target) == 50), "atomic_get");
|
||||
|
||||
/* atomic_ptr_get() */
|
||||
ptr_target = (atomic_ptr_t)50;
|
||||
zassert_true((atomic_ptr_get(&ptr_target) == (void *)50),
|
||||
ptr_target = ATOMIC_PTR_INIT((void *)50);
|
||||
zassert_true((atomic_ptr_get(&ptr_target) == (atomic_ptr_val_t)50),
|
||||
"atomic_ptr_get");
|
||||
|
||||
/* atomic_set() */
|
||||
|
@ -158,9 +158,9 @@ void test_atomic(void)
|
|||
zassert_true((target == value), "atomic_set");
|
||||
|
||||
/* atomic_ptr_set() */
|
||||
ptr_target = (atomic_ptr_t)42;
|
||||
ptr_value = (void *)77;
|
||||
zassert_true((atomic_ptr_set(&ptr_target, ptr_value) == (void *)42),
|
||||
ptr_target = ATOMIC_PTR_INIT((void *)42);
|
||||
ptr_value = (atomic_ptr_val_t)77;
|
||||
zassert_true((atomic_ptr_set(&ptr_target, ptr_value) == (atomic_ptr_val_t)42),
|
||||
"atomic_ptr_set");
|
||||
zassert_true((ptr_target == ptr_value), "atomic_ptr_set");
|
||||
|
||||
|
@ -170,8 +170,8 @@ void test_atomic(void)
|
|||
zassert_true((target == 0), "atomic_clear");
|
||||
|
||||
/* atomic_ptr_clear() */
|
||||
ptr_target = (atomic_ptr_t)100;
|
||||
zassert_true((atomic_ptr_clear(&ptr_target) == (void *)100),
|
||||
ptr_target = ATOMIC_PTR_INIT((void *)100);
|
||||
zassert_true((atomic_ptr_clear(&ptr_target) == (atomic_ptr_val_t)100),
|
||||
"atomic_ptr_clear");
|
||||
zassert_true((ptr_target == NULL), "atomic_ptr_clear");
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue