Files
cKit/Foundation/c_Atomic.h
T
2026-08-29 01:50:50 +08:00

148 lines
7.1 KiB
C

#ifndef INCLUDED_C_ATOMIC_H
#define INCLUDED_C_ATOMIC_H
#ifndef INCLUDED_C_TYPES_H
#include <c_Types.h>
#endif /*INCLUDED_C_TYPES_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
#if defined(_MSC_VER)
#include <windows.h>
// 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*/