diff --git a/include/sys/atomic.h b/include/sys/atomic.h index 99f34f1d7061..774e5042afd5 100644 --- a/include/sys/atomic.h +++ b/include/sys/atomic.h @@ -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 */ diff --git a/include/sys/atomic_builtin.h b/include/sys/atomic_builtin.h index e9912ee5f418..44dbbe8931f7 100644 --- a/include/sys/atomic_builtin.h +++ b/include/sys/atomic_builtin.h @@ -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); } diff --git a/include/sys/atomic_c.h b/include/sys/atomic_c.h index 5f0c6807ec67..ee368c28f428 100644 --- a/include/sys/atomic_c.h +++ b/include/sys/atomic_c.h @@ -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); diff --git a/kernel/atomic_c.c b/kernel/atomic_c.c index 948f15b1dfb3..ae1dcda64401 100644 --- a/kernel/atomic_c.c +++ b/kernel/atomic_c.c @@ -107,8 +107,8 @@ bool z_vrfy_atomic_cas(atomic_t *target, atomic_val_t old_value, #include #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))); diff --git a/tests/kernel/common/src/atomic.c b/tests/kernel/common/src/atomic.c index 7611fd0b188a..020f5054cd95 100644 --- a/tests/kernel/common/src/atomic.c +++ b/tests/kernel/common/src/atomic.c @@ -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");