#ifndef INCLUDED_C_ATOMIC_H #define INCLUDED_C_ATOMIC_H #ifndef INCLUDED_C_TYPES_H #include #endif /*INCLUDED_C_TYPES_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #if defined(_MSC_VER) #include // Windows 平台原子型態定義 typedef volatile char c_atomic_8_t; typedef volatile long c_atomic_32_t; typedef volatile __int64 c_atomic_64_t; typedef volatile int c_atomic_int_t; typedef void* volatile c_atomic_ptr_t; typedef volatile char c_atomic_bool_t; // MSVC 8-Bit (uint8_t/bool) 原子加減法模擬 (利用 CAS 迴圈確保硬體原子性) static inline char _msvc_atomic_fetch_add_8(volatile char* p, char v) { char old_val; do { old_val = *p; } while (InterlockedCompareExchange8((volatile char*)p, (char)(old_val + v), old_val) != old_val); return old_val; } static inline char _msvc_atomic_fetch_sub_8(volatile char* p, char v) { char old_val; do { old_val = *p; } while (InterlockedCompareExchange8((volatile char*)p, (char)(old_val - v), old_val) != old_val); return old_val; } #elif defined(__GNUC__) || defined(__clang__) // GCC/Clang 平台原子型態定義 (與標準 C 原始型態無縫相容) typedef int8_t c_atomic_8_t; typedef int32_t c_atomic_32_t; typedef int64_t c_atomic_64_t; typedef int c_atomic_int_t; typedef void* c_atomic_ptr_t; typedef bool c_atomic_bool_t; // GCC/Clang 內建函數自帶全自動型態泛型 #define _C_ATOMIC_LOAD_ANY(p) __atomic_load_n((p), __ATOMIC_SEQ_CST) #define _C_ATOMIC_ADD_ANY(p, v) __atomic_fetch_add((p), (v), __ATOMIC_SEQ_CST) #define _C_ATOMIC_SUB_ANY(p, v) __atomic_fetch_sub((p), (v), __ATOMIC_SEQ_CST) #define _C_ATOMIC_EXCH_ANY(p, v) __atomic_exchange_n((p), (v), __ATOMIC_SEQ_CST) #else #error "當前編譯器環境不支援硬體級跨平台原子操作!" #endif /* ================================================================================================================== */ /* 2. 強型態的特化 API 提供 */ #define c_atomic_init_8(p, v) (*(p) = (v)) #define c_atomic_init_32(p, v) (*(p) = (v)) #define c_atomic_init_64(p, v) (*(p) = (v)) #define c_atomic_init_int(p, v) (*(p) = (v)) #define c_atomic_init_ptr(p, v) (*(p) = (v)) #define c_atomic_init_bool(p, v) (*(p) = (v)) #ifdef _MSC_VER // ---- 8-Bit (uint8_t) ---- #define c_atomic_load_8(p) InterlockedCompareExchange8((volatile char*)(p), 0, 0) #define c_atomic_fetch_add_8(p, v) _msvc_atomic_fetch_add_8((volatile char*)(p), (char)(v)) #define c_atomic_fetch_sub_8(p, v) _msvc_atomic_fetch_sub_8((volatile char*)(p), (char)(v)) // ---- 32-Bit ---- #define c_atomic_load_32(p) InterlockedCompareExchange((volatile LONG*)(p), 0, 0) #define c_atomic_fetch_add_32(p, v) InterlockedExchangeAdd((volatile LONG*)(p), (LONG)(v)) #define c_atomic_fetch_sub_32(p, v) InterlockedExchangeAdd((volatile LONG*)(p), -(LONG)(v)) // ---- 64-Bit ---- #define c_atomic_load_64(p) InterlockedCompareExchange64((volatile LONG64*)(p), 0, 0) #define c_atomic_fetch_add_64(p, v) InterlockedExchangeAdd64((volatile LONG64*)(p), (LONGLONG)(v)) #define c_atomic_fetch_sub_64(p, v) InterlockedExchangeAdd64((volatile LONG64*)(p), -(LONGLONG)(v)) // ---- Pointer (void*) ---- #define c_atomic_load_ptr(p) InterlockedCompareExchangePointer((void* volatile*)(p), NULL, NULL) #define c_atomic_exchange_ptr(p, v) InterlockedExchangePointer((void* volatile*)(p), (void*)(v)) // ---- Bool ---- #define c_atomic_load_bool(p) (InterlockedCompareExchange8((volatile char*)(p), 0, 0) != 0) #define c_atomic_exchange_bool(p, v) (InterlockedExchange8((volatile char*)(p), (char)(v)) != 0) #else // GCC/Clang 特化映射(全型態直接套用系統內建泛型,編譯效率極高) #define c_atomic_load_8(p) _C_ATOMIC_LOAD_ANY(p) #define c_atomic_fetch_add_8(p, v) _C_ATOMIC_ADD_ANY(p, v) #define c_atomic_fetch_sub_8(p, v) _C_ATOMIC_SUB_ANY(p, v) #define c_atomic_load_32(p) _C_ATOMIC_LOAD_ANY(p) #define c_atomic_fetch_add_32(p, v) _C_ATOMIC_ADD_ANY(p, v) #define c_atomic_fetch_sub_32(p, v) _C_ATOMIC_SUB_ANY(p, v) #define c_atomic_load_64(p) _C_ATOMIC_LOAD_ANY(p) #define c_atomic_fetch_add_64(p, v) _C_ATOMIC_ADD_ANY(p, v) #define c_atomic_fetch_sub_64(p, v) _C_ATOMIC_SUB_ANY(p, v) #define c_atomic_load_ptr(p) _C_ATOMIC_LOAD_ANY(p) #define c_atomic_exchange_ptr(p, v) _C_ATOMIC_EXCH_ANY(p, v) #define c_atomic_load_bool(p) _C_ATOMIC_LOAD_ANY(p) #define c_atomic_exchange_bool(p, v) _C_ATOMIC_EXCH_ANY(p, v) #endif // 原生 Int 動態配適映射 #define c_atomic_load_int(p) (sizeof(int) == 8 ? (int)c_atomic_load_64((c_atomic_64_t*)(p)) : (int)c_atomic_load_32((c_atomic_32_t*)(p))) #define c_atomic_fetch_add_int(p, v) (sizeof(int) == 8 ? (int)c_atomic_fetch_add_64((c_atomic_64_t*)(p), v) : (int)c_atomic_fetch_add_32((c_atomic_32_t*)(p), v)) #define c_atomic_fetch_sub_int(p, v) (sizeof(int) == 8 ? (int)c_atomic_fetch_sub_64((c_atomic_64_t*)(p), v) : (int)c_atomic_fetch_sub_32((c_atomic_32_t*)(p), v)) /* ================================================================================================================== */ /* 3. 全型態 C11 _Generic 萬能泛型巨集分派 */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define C_ATOMIC_LOAD(p) _Generic(*(p), \ bool: c_atomic_load_bool((c_atomic_bool_t*)(p)), \ int8_t: c_atomic_load_8((c_atomic_8_t*)(p)), \ uint8_t: c_atomic_load_8((c_atomic_8_t*)(p)), \ int32_t: c_atomic_load_32((c_atomic_32_t*)(p)), \ uint32_t: c_atomic_load_32((c_atomic_32_t*)(p)), \ int64_t: c_atomic_load_64((c_atomic_64_t*)(p)), \ uint64_t: c_atomic_load_64((c_atomic_64_t*)(p)), \ void*: c_atomic_load_ptr((c_atomic_ptr_t*)(p)) \ ) #define C_ATOMIC_FETCH_ADD(p, v) _Generic(*(p), \ int8_t: c_atomic_fetch_add_8((c_atomic_8_t*)(p), (v)), \ uint8_t: c_atomic_fetch_add_8((c_atomic_8_t*)(p), (v)), \ int32_t: c_atomic_fetch_add_32((c_atomic_32_t*)(p), (v)), \ uint32_t: c_atomic_fetch_add_32((c_atomic_32_t*)(p), (v)), \ int64_t: c_atomic_fetch_add_64((c_atomic_64_t*)(p), (v)), \ uint64_t: c_atomic_fetch_add_64((c_atomic_64_t*)(p), (v)) \ ) #define C_ATOMIC_FETCH_SUB(p, v) _Generic(*(p), \ int8_t: c_atomic_fetch_sub_8((c_atomic_8_t*)(p), (v)), \ uint8_t: c_atomic_fetch_sub_8((c_atomic_8_t*)(p), (v)), \ int32_t: c_atomic_fetch_sub_32((c_atomic_32_t*)(p), (v)), \ uint32_t: c_atomic_fetch_sub_32((c_atomic_32_t*)(p), (v)), \ int64_t: c_atomic_fetch_sub_64((c_atomic_64_t*)(p), (v)), \ uint64_t: c_atomic_fetch_sub_64((c_atomic_64_t*)(p), (v)) \ ) #endif #endif /*INCLUDED_C_ATOMIC_H*/