mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-03 22:08:28 +00:00 
			
		
		
		
	newlib,clang: implement __sync_* atomics for clang/llvm toolchain.
This commit is contained in:
		
				
					committed by
					
						
						Scott Mabin
					
				
			
			
				
	
			
			
			
						parent
						
							d4f2e03e4a
						
					
				
				
					commit
					de5e0fa3bd
				
			@@ -75,6 +75,24 @@ static portMUX_TYPE s_atomic_lock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
 | 
			
		||||
#endif // SOC_CPU_CORES_NUM
 | 
			
		||||
 | 
			
		||||
#ifdef __clang__
 | 
			
		||||
// Clang doesn't allow to define "__sync_*" atomics. The workaround is to define function with name "__sync_*_builtin",
 | 
			
		||||
// which implements "__sync_*" atomic functionality and use asm directive to set the value of symbol "__sync_*" to the name
 | 
			
		||||
// of defined function.
 | 
			
		||||
 | 
			
		||||
#define CLANG_ATOMIC_SUFFIX(name_) name_ ## _builtin
 | 
			
		||||
#define CLANG_DECLARE_ALIAS(name_) \
 | 
			
		||||
__asm__(".type " # name_ ", @function\n"        \
 | 
			
		||||
        ".global " #name_ "\n"                  \
 | 
			
		||||
        ".equ " #name_ ", " #name_ "_builtin");
 | 
			
		||||
 | 
			
		||||
#else // __clang__
 | 
			
		||||
 | 
			
		||||
#define CLANG_ATOMIC_SUFFIX(name_) name_
 | 
			
		||||
#define CLANG_DECLARE_ALIAS(name_)
 | 
			
		||||
 | 
			
		||||
#endif // __clang__
 | 
			
		||||
 | 
			
		||||
#define ATOMIC_LOAD(n, type) type __atomic_load_ ## n (const type* mem, int memorder) \
 | 
			
		||||
{                                                   \
 | 
			
		||||
    unsigned state = _ATOMIC_ENTER_CRITICAL();      \
 | 
			
		||||
@@ -158,12 +176,14 @@ static portMUX_TYPE s_atomic_lock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
    return ret; \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SYNC_FETCH_OP(op, n, type) type __sync_fetch_and_ ## op ##_ ## n (type* ptr, type value) \
 | 
			
		||||
{                                                                               \
 | 
			
		||||
    return __atomic_fetch_ ## op ##_ ## n (ptr, value, __ATOMIC_SEQ_CST);       \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SYNC_BOOL_CMP_EXCHANGE(n, type) bool  __sync_bool_compare_and_swap_ ## n  (type *ptr, type oldval, type newval) \
 | 
			
		||||
#define SYNC_FETCH_OP(op, n, type) type CLANG_ATOMIC_SUFFIX(__sync_fetch_and_ ## op ##_ ## n) (type* ptr, type value) \
 | 
			
		||||
{                                                                                \
 | 
			
		||||
    return __atomic_fetch_ ## op ##_ ## n (ptr, value, __ATOMIC_SEQ_CST);        \
 | 
			
		||||
}                                                                                \
 | 
			
		||||
CLANG_DECLARE_ALIAS( __sync_fetch_and_ ## op ##_ ## n )
 | 
			
		||||
 | 
			
		||||
#define SYNC_BOOL_CMP_EXCHANGE(n, type) bool  CLANG_ATOMIC_SUFFIX(__sync_bool_compare_and_swap_ ## n)  (type *ptr, type oldval, type newval) \
 | 
			
		||||
{                                                                                \
 | 
			
		||||
    bool ret = false;                                                            \
 | 
			
		||||
    unsigned state = _ATOMIC_ENTER_CRITICAL();                                   \
 | 
			
		||||
@@ -173,9 +193,10 @@ static portMUX_TYPE s_atomic_lock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
    }                                                                            \
 | 
			
		||||
    _ATOMIC_EXIT_CRITICAL(state);                                                \
 | 
			
		||||
    return ret;                                                                  \
 | 
			
		||||
}
 | 
			
		||||
}                                                                                \
 | 
			
		||||
CLANG_DECLARE_ALIAS( __sync_bool_compare_and_swap_ ## n )
 | 
			
		||||
 | 
			
		||||
#define SYNC_VAL_CMP_EXCHANGE(n, type) type  __sync_val_compare_and_swap_ ## n  (type *ptr, type oldval, type newval) \
 | 
			
		||||
#define SYNC_VAL_CMP_EXCHANGE(n, type) type  CLANG_ATOMIC_SUFFIX(__sync_val_compare_and_swap_ ## n)  (type *ptr, type oldval, type newval) \
 | 
			
		||||
{                                                                                \
 | 
			
		||||
    unsigned state = _ATOMIC_ENTER_CRITICAL();                                   \
 | 
			
		||||
    type ret = *ptr;                                                             \
 | 
			
		||||
@@ -184,7 +205,9 @@ static portMUX_TYPE s_atomic_lock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
    }                                                                            \
 | 
			
		||||
    _ATOMIC_EXIT_CRITICAL(state);                                                \
 | 
			
		||||
    return ret;                                                                  \
 | 
			
		||||
}
 | 
			
		||||
}                                                                                \
 | 
			
		||||
CLANG_DECLARE_ALIAS( __sync_val_compare_and_swap_ ## n )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if !HAS_ATOMICS_32
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user