atomic:Add more interfaces

Summary:
  1. add atomic_flag_test_and_set and atomic_flag_clear
  2. add typedef memory_order
  3. add atomic_flag

Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
This commit is contained in:
chenrun1 2024-08-08 16:04:32 +08:00 committed by Xiang Xiao
parent cfcf347515
commit 900e713cd0
3 changed files with 85 additions and 8 deletions

View File

@ -33,6 +33,7 @@ extern "C++"
# define ATOMIC_VAR_INIT(value) (value)
using std::memory_order;
using std::atomic_bool;
using std::atomic_char;
using std::atomic_schar;
@ -56,6 +57,10 @@ extern "C++"
using std::atomic_compare_exchange_strong_explicit;
using std::atomic_compare_exchange_weak;
using std::atomic_compare_exchange_weak_explicit;
using std::atomic_flag_test_and_set;
using std::atomic_flag_test_and_set_explicit;
using std::atomic_flag_clear;
using std::atomic_flag_clear_explicit;
using std::atomic_fetch_add;
using std::atomic_fetch_add_explicit;
using std::atomic_fetch_sub;
@ -67,7 +72,9 @@ extern "C++"
using std::atomic_fetch_xor;
using std::atomic_fetch_xor_explicit;
}
# elif __has_include(<stdatomic.h>)
# elif __has_include(<stdatomic.h>) && \
((defined(__cplusplus) && __cplusplus >= 201103L) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L))
# if !(__clang__) && defined(__cplusplus)
# define _Atomic
# endif

View File

@ -56,6 +56,7 @@
# define __ATOMIC_SEQ_CST 5
#endif
#define ATOMIC_FLAG_INIT 0
#define ATOMIC_VAR_INIT(value) (value)
#define atomic_store_n(obj, val, type) \
@ -101,14 +102,16 @@
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, success, failure) \
atomic_compare_exchange_n(obj, expected, desired, true, success, failure)
#define atomic_fetch_or_n(obj, val, type) \
(sizeof(*(obj)) == 1 ? __atomic_fetch_or_1(obj, val, type) : \
sizeof(*(obj)) == 2 ? __atomic_fetch_or_2(obj, val, type) : \
sizeof(*(obj)) == 4 ? __atomic_fetch_or_4(obj, val, type) : \
__atomic_fetch_or_8(obj, val, type))
#define atomic_flag_test_and_set_n(obj, type) \
(sizeof(*(obj)) == 1 ? __atomic_flag_test_and_set_1(obj, type) : \
sizeof(*(obj)) == 2 ? __atomic_flag_test_and_set_2(obj, type) : \
sizeof(*(obj)) == 4 ? __atomic_flag_test_and_set_4(obj, type) : \
__atomic_flag_test_and_set_8(obj, type))
#define atomic_fetch_or(obj, val) atomic_fetch_or_n(obj, val, __ATOMIC_RELAXED)
#define atomic_fetch_or_explicit(obj, val, type) atomic_fetch_or_n(obj, val, type)
#define atomic_flag_test_and_set(obj) atomic_flag_test_and_set_n(obj, __ATOMIC_RELAXED)
#define atomic_flag_test_and_set_explicit(obj, type) atomic_flag_test_and_set_n(obj, 1, type)
#define atomic_flag_clear(obj) atomic_store(obj, 0)
#define atomic_flag_clear_explicit(obj, type) atomic_store_explicit(obj, 0, type)
#define atomic_fetch_and_n(obj, val, type) \
(sizeof(*(obj)) == 1 ? __atomic_fetch_and_1(obj, val, type) : \
@ -119,6 +122,15 @@
#define atomic_fetch_and(obj, val) atomic_fetch_and_n(obj, val, __ATOMIC_RELAXED)
#define atomic_fetch_and_explicit(obj, val, type) atomic_fetch_and_n(obj, val, type)
#define atomic_fetch_or_n(obj, val, type) \
(sizeof(*(obj)) == 1 ? __atomic_fetch_or_1(obj, val, type) : \
sizeof(*(obj)) == 2 ? __atomic_fetch_or_2(obj, val, type) : \
sizeof(*(obj)) == 4 ? __atomic_fetch_or_4(obj, val, type) : \
__atomic_fetch_or_8(obj, val, type))
#define atomic_fetch_or(obj, val) atomic_fetch_or_n(obj, val, __ATOMIC_RELAXED)
#define atomic_fetch_or_explicit(obj, val, type) atomic_fetch_or_n(obj, val, type)
#define atomic_fetch_xor_n(obj, val, type) \
(sizeof(*(obj)) == 1 ? __atomic_fetch_xor_1(obj, val, type) : \
sizeof(*(obj)) == 2 ? __atomic_fetch_xor_2(obj, val, type) : \
@ -150,6 +162,17 @@
* Public Types
****************************************************************************/
typedef enum
{
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST
} memory_order;
typedef volatile int atomic_flag;
typedef volatile bool atomic_bool;
typedef volatile char atomic_char;
typedef volatile signed char atomic_schar;
@ -196,6 +219,14 @@ bool __atomic_compare_exchange_4(FAR volatile void *mem, FAR void *expect,
bool __atomic_compare_exchange_8(FAR volatile void *mem, FAR void *expect,
uint64_t desired, bool weak, int success,
int failure);
uint8_t __atomic_flag_test_and_set_1(FAR const volatile void *ptr,
int memorder);
uint16_t __atomic_flag_test_and_set_2(FAR const volatile void *ptr,
int memorder);
uint32_t __atomic_flag_test_and_set_4(FAR const volatile void *ptr,
int memorder);
uint64_t __atomic_flag_test_and_set_8(FAR const volatile void *ptr,
int memorder);
uint8_t __atomic_fetch_add_1(FAR volatile void *ptr, uint8_t value,
int memorder);
uint16_t __atomic_fetch_add_2(FAR volatile void *ptr, uint16_t value,

View File

@ -98,6 +98,21 @@
return ret; \
}
#define FLAG_TEST_AND_SET(n, type) \
\
type weak_function __atomic_flags_test_and_set##n (FAR volatile void *ptr, \
int memorder) \
{ \
irqstate_t irqstate = spin_lock_irqsave(NULL); \
FAR type *tmp = (FAR type *)ptr; \
type ret = *tmp; \
\
*(FAR type *)ptr = 1; \
\
spin_unlock_irqrestore(NULL, irqstate); \
return ret; \
}
#define FETCH_ADD(n, type) \
\
type weak_function __atomic_fetch_add_##n (FAR volatile void *ptr, \
@ -396,6 +411,30 @@ CMP_EXCHANGE(4, uint32_t)
CMP_EXCHANGE(8, uint64_t)
/****************************************************************************
* Name: __atomic_flag_test_and_set_1
****************************************************************************/
FLAG_TEST_AND_SET(1, uint8_t)
/****************************************************************************
* Name: __atomic_flag_test_and_set_2
****************************************************************************/
FLAG_TEST_AND_SET(2, uint16_t)
/****************************************************************************
* Name: __atomic_flag_test_and_set_4
****************************************************************************/
FLAG_TEST_AND_SET(4, uint32_t)
/****************************************************************************
* Name: __atomic_flag_test_and_set_8
****************************************************************************/
FLAG_TEST_AND_SET(8, uint64_t)
/****************************************************************************
* Name: __atomic_fetch_add_1
****************************************************************************/