From af67317b269aaf991550cc1c8720c1d310b6a401 Mon Sep 17 00:00:00 2001 From: Lawrence Stubbs Date: Fri, 27 Sep 2024 07:20:35 -0400 Subject: [PATCH] start using standard C11 names, fix armv7 issues --- CMakeLists.txt | 2 +- catomic.h | 126 +++++++++++++++++++++++++++++-------------------- rpmalloc.c | 64 ++++++++++++++++++------- 3 files changed, 124 insertions(+), 68 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d419c2a..6834941a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8...3.14) project( cthread - VERSION 4.0.1.19 + VERSION 4.0.2.0 DESCRIPTION "Emulated C11 threads and thread pool, with custom malloc replacement." HOMEPAGE_URL "https://github.com/zelang-dev/cthread" LANGUAGES C diff --git a/catomic.h b/catomic.h index 47ad3ae5..aa8f52eb 100644 --- a/catomic.h +++ b/catomic.h @@ -1319,7 +1319,7 @@ typedef unsigned char c89atomic_bool; #define c89atomic_thread_fence(order) __asm__ __volatile__("lock; addl $0, (%%esp)" ::: "memory", "cc") #elif defined(C89ATOMIC_X64) #define c89atomic_thread_fence(order) __asm__ __volatile__("lock; addq $0, (%%rsp)" ::: "memory", "cc") - #else + #elif !defined(__TINYC__) #error Unsupported architecture. Please submit a feature request. #endif @@ -1330,10 +1330,12 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64) #if defined(__TINYC__) && defined(_WIN32) && defined(__arm__) && !defined(_MSC_VER) - return (c89atomic_uint8)atomic_compare_exchange_strong((atomic_uchar *)dst, (unsigned char*)&expected, (unsigned char)desired); + result = (c89atomic_uint8)atomic_compare_exchange_strong((atomic_uchar *)dst, (unsigned char*)&expected, (unsigned char)desired); #else __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc"); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint8)atomic_compare_exchange_strong((atomic_uchar *)dst, (unsigned char *)&expected, (unsigned char)desired); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1347,10 +1349,12 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64) #if defined(__TINYC__) && defined(_WIN32) && defined(__arm__) && !defined(_MSC_VER) - return (c89atomic_uint16)atomic_compare_exchange_strong((atomic_ushort *)dst, (unsigned short*)&expected, (unsigned short)desired); + result = (c89atomic_uint16)atomic_compare_exchange_strong((atomic_ushort *)dst, (unsigned short*)&expected, (unsigned short)desired); #else __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc"); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint16)atomic_compare_exchange_strong((atomic_ushort *)dst, (unsigned short *)&expected, (unsigned short)desired); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1364,10 +1368,12 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64) #if defined(__TINYC__) && defined(_WIN32) && defined(__arm__) && !defined(_MSC_VER) - return (c89atomic_uint32)atomic_compare_exchange_strong((atomic_int *)dst, (unsigned int*)&expected, (unsigned int)desired); + result = (c89atomic_uint32)atomic_compare_exchange_strong((atomic_int *)dst, (unsigned int*)&expected, (unsigned int)desired); #else __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc"); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint32)atomic_compare_exchange_strong((atomic_int *)dst, (unsigned int *)&expected, (unsigned int)desired); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1389,13 +1395,15 @@ typedef unsigned char c89atomic_bool; c89atomic_uint32 resultEAX; c89atomic_uint32 resultEDX; #if defined(__TINYC__) && defined(_WIN32) && defined(__arm__) && !defined(_MSC_VER) - return (c89atomic_uint64)atomic_compare_exchange_strong((atomic_ulong *)dst, (unsigned long*)&expected, (unsigned long)desired); + result = (c89atomic_uint64)atomic_compare_exchange_strong((atomic_ulong *)dst, (unsigned long*)&expected, (unsigned long)desired); #else __asm__ __volatile__("push %%ebx; xchg %5, %%ebx; lock; cmpxchg8b %0; pop %%ebx" : "+m"(*dst), "=a"(resultEAX), "=d"(resultEDX) : "a"(expected & 0xFFFFFFFF), "d"(expected >> 32), "r"(desired & 0xFFFFFFFF), "c"(desired >> 32) : "cc"); result = ((c89atomic_uint64)resultEDX << 32) | resultEAX; #endif #elif defined(C89ATOMIC_X64) __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc"); + #elif defined(__TINYC__) + result = (c89atomic_uint64)atomic_compare_exchange_strong((atomic_ulong *)dst, (unsigned long *)&expected, (unsigned long)desired); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1413,10 +1421,12 @@ typedef unsigned char c89atomic_bool; #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64) #if defined(__TINYC__) && defined(_WIN32) && defined(__arm__) && !defined(_MSC_VER) - return (c89atomic_uint8)atomic_exchange_explicit((atomic_uchar *)dst, (unsigned char)src, order); + result = (c89atomic_uint8)atomic_exchange_explicit((atomic_uchar *)dst, (unsigned char)src, order); #else __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src)); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint8)atomic_exchange_explicit((atomic_uchar *)dst, (unsigned char)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1436,6 +1446,8 @@ typedef unsigned char c89atomic_bool; #else __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src)); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint16)atomic_exchange_explicit((atomic_ushort *)dst, (unsigned short)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1455,6 +1467,8 @@ typedef unsigned char c89atomic_bool; #else __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src)); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint32)atomic_exchange_explicit((atomic_uint *)dst, (unsigned int)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1478,6 +1492,8 @@ typedef unsigned char c89atomic_bool; #else __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src)); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint64)atomic_exchange_explicit((atomic_ulong *)dst, (unsigned long)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1499,6 +1515,8 @@ typedef unsigned char c89atomic_bool; #else __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc"); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint8)atomic_fetch_add_explicit((atomic_uchar *)dst, (unsigned char)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1518,6 +1536,8 @@ typedef unsigned char c89atomic_bool; #else __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc"); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint16)atomic_fetch_add_explicit((atomic_ushort *)dst, (unsigned short)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1537,6 +1557,8 @@ typedef unsigned char c89atomic_bool; #else __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc"); #endif + #elif defined(__TINYC__) + result = (c89atomic_uint16)atomic_fetch_add_explicit((atomic_uint *)dst, (unsigned int)src, order); #else #error Unsupported architecture. Please submit a feature request. #endif @@ -1570,6 +1592,8 @@ typedef unsigned char c89atomic_bool; #endif return result; + #elif defined(__TINYC__) + return (c89atomic_uint64)atomic_fetch_add_explicit((atomic_ulong *)dst, (unsigned long)src, order); #endif } @@ -2626,10 +2650,10 @@ make_atomic(void *, atomic_ptr_t) #if defined(__i386__) || defined(__ppc__) || defined(__arm__) || defined(_M_ARM) || defined(__i386) || defined(_M_IX86) /* reads a value from an atomic object then cast to type */ -# define atomic_get(type, obj) (type)c89atomic_load_32((c89atomic_uint32 *)obj) +# define atomic_get(type, obj) (type)c89atomic_load_32((atomic_uint *)obj) #else /* reads a value from an atomic object then cast to type */ -# define atomic_get(type, obj) (type)c89atomic_load_64((c89atomic_uint64 *)obj) +# define atomic_get(type, obj) (type)c89atomic_load_64((atomic_ullong *)obj) #endif #if !defined(_STDATOMIC_H) @@ -2654,130 +2678,130 @@ make_atomic(void *, atomic_ptr_t) #if defined(__i386__) || defined(__ppc__) || defined(__arm__) || defined(_M_ARM) || defined(__i386) || defined(_M_IX86) /* sets an atomic_flag to true and returns the old value */ -#define atomic_is_lock_free(obj) c89atomic_is_lock_free_32((c89atomic_uint32 *)obj) +#define atomic_is_lock_free(obj) c89atomic_is_lock_free_32((atomic_uint *)obj) /* stores a value in an atomic object */ -#define atomic_store(obj, desired) c89atomic_store_32((c89atomic_uint32 *)obj, (c89atomic_uint32)desired) +#define atomic_store(obj, desired) c89atomic_store_32((atomic_uint *)obj, (c89atomic_uint32)desired) /* stores a value in an atomic object */ -#define atomic_store_explicit(obj, desired, order) c89atomic_store_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)desired, order) +#define atomic_store_explicit(obj, desired, order) c89atomic_store_explicit_32((atomic_uint *)obj, (c89atomic_uint32)desired, order) /* reads a value from an atomic object */ -#define atomic_load(obj) c89atomic_load_32((c89atomic_uint32 *)obj) +#define atomic_load(obj) c89atomic_load_32((atomic_uint *)obj) /* reads a value from an atomic object */ -#define atomic_load_explicit(obj, order) c89atomic_load_explicit_32((c89atomic_uint32 *)obj, order) +#define atomic_load_explicit(obj, order) c89atomic_load_explicit_32((atomic_uint *)obj, order) /* initializes an existing atomic object */ -#define atomic_init(obj, desired) c89atomic_store_32((c89atomic_uint32 *)obj, (c89atomic_uint32)desired) +#define atomic_init(obj, desired) c89atomic_store_32((atomic_uint *)obj, (c89atomic_uint32)desired) /* atomic addition */ -#define atomic_fetch_add(obj, arg) c89atomic_fetch_add_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg) +#define atomic_fetch_add(obj, arg) c89atomic_fetch_add_32((atomic_uint *)obj, (c89atomic_uint32)arg) /* atomic addition */ -#define atomic_fetch_add_explicit(obj, arg, order) c89atomic_fetch_add_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg, order) +#define atomic_fetch_add_explicit(obj, arg, order) c89atomic_fetch_add_explicit_32((atomic_uint *)obj, (c89atomic_uint32)arg, order) /* atomic subtraction */ -#define atomic_fetch_sub(obj, arg) c89atomic_fetch_sub_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg) +#define atomic_fetch_sub(obj, arg) c89atomic_fetch_sub_32((atomic_uint *)obj, (c89atomic_uint32)arg) /* atomic subtraction */ -#define atomic_fetch_sub_explicit(obj, arg, order) c89atomic_fetch_sub_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg, order) +#define atomic_fetch_sub_explicit(obj, arg, order) c89atomic_fetch_sub_explicit_32((atomic_uint *)obj, (c89atomic_uint32)arg, order) /* atomic bitwise OR */ -#define atomic_fetch_or(obj, arg) c89atomic_fetch_or_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg) +#define atomic_fetch_or(obj, arg) c89atomic_fetch_or_32((atomic_uint *)obj, (c89atomic_uint32)arg) /* atomic bitwise OR */ -#define atomic_fetch_or_explicit(obj, arg, order) c89atomic_fetch_or_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg, order) +#define atomic_fetch_or_explicit(obj, arg, order) c89atomic_fetch_or_explicit_32((atomic_uint *)obj, (c89atomic_uint32)arg, order) /* atomic bitwise exclusive OR */ -#define atomic_fetch_xor(obj, arg) c89atomic_fetch_xor_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg) +#define atomic_fetch_xor(obj, arg) c89atomic_fetch_xor_32((atomic_uint *)obj, (c89atomic_uint32)arg) /* atomic bitwise exclusive OR */ -#define atomic_fetch_xor_explicit(obj, arg, order) c89atomic_fetch_xor_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg, order) +#define atomic_fetch_xor_explicit(obj, arg, order) c89atomic_fetch_xor_explicit_32((atomic_uint *)obj, (c89atomic_uint32)arg, order) /* atomic bitwise AND */ #define atomic_fetch_and(obj, arg) \ - c89atomic_fetch_and_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg) + c89atomic_fetch_and_32((atomic_uint *)obj, (c89atomic_uint32)arg) /* atomic bitwise AND */ #define atomic_fetch_and_explicit(obj, arg, order) \ - c89atomic_fetch_and_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)arg, order) + c89atomic_fetch_and_explicit_32((atomic_uint *)obj, (c89atomic_uint32)arg, order) /* swaps a value with the value of an atomic object */ #define atomic_exchange(obj, desired) \ - c89atomic_exchange_32((c89atomic_uint32 *)obj, (c89atomic_uint32)desired) + c89atomic_exchange_32((atomic_uint *)obj, (c89atomic_uint32)desired) /* swaps a value with the value of an atomic object */ #define atomic_exchange_explicit(obj, desired, order) \ - c89atomic_exchange_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)desired, order) + c89atomic_exchange_explicit_32((atomic_uint *)obj, (c89atomic_uint32)desired, order) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ -#define atomic_compare_exchange_weak(obj, expected, desired) atomic_cas_32((c89atomic_uint32 *)obj, (c89atomic_uint32)expected, desired) +#define atomic_compare_exchange_weak(obj, expected, desired) atomic_cas_32((atomic_uint *)obj, (c89atomic_uint32)expected, desired) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ - c89atomic_compare_exchange_weak_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)expected, (c89atomic_uint32)desired, succ, fail) + c89atomic_compare_exchange_weak_explicit_32((atomic_uint *)obj, (c89atomic_uint32)expected, (c89atomic_uint32)desired, succ, fail) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ -#define atomic_compare_exchange_strong(obj, expected, desired) atomic_cas_32((c89atomic_uint32 *)obj, (c89atomic_uint32)expected, desired) +#define atomic_compare_exchange_strong(obj, expected, desired) atomic_cas_32((atomic_uint *)obj, (c89atomic_uint32)expected, desired) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ - c89atomic_compare_exchange_strong_explicit_32((c89atomic_uint32 *)obj, (c89atomic_uint32)expected, (c89atomic_uint32)desired, succ, fail) + c89atomic_compare_exchange_strong_explicit_32((atomic_uint *)obj, (c89atomic_uint32)expected, (c89atomic_uint32)desired, succ, fail) #else /* indicates whether the atomic object is lock-free */ -#define atomic_is_lock_free(obj) c89atomic_is_lock_free_64((c89atomic_uint64 *)obj) +#define atomic_is_lock_free(obj) c89atomic_is_lock_free_64((atomic_ullong *)obj) /* stores a value in an atomic object */ -#define atomic_store(obj, desired) c89atomic_store_64((c89atomic_uint64 *)obj, (c89atomic_uint64)desired) +#define atomic_store(obj, desired) c89atomic_store_64((atomic_ullong *)obj, (c89atomic_uint64)desired) /* stores a value in an atomic object */ -#define atomic_store_explicit(obj, desired, order) c89atomic_store_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)desired, order) +#define atomic_store_explicit(obj, desired, order) c89atomic_store_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)desired, order) /* reads a value from an atomic object */ -#define atomic_load(obj) c89atomic_load_64((c89atomic_uint64 *)obj) +#define atomic_load(obj) c89atomic_load_64((atomic_ullong *)obj) /* reads a value from an atomic object */ -#define atomic_load_explicit(obj, order) c89atomic_load_explicit_64((c89atomic_uint64 *)obj, order) +#define atomic_load_explicit(obj, order) c89atomic_load_explicit_64((atomic_ullong *)obj, order) /* initializes an existing atomic object */ -#define atomic_init(obj, desired) c89atomic_store_64((c89atomic_uint64 *)obj, (c89atomic_uint64)desired) +#define atomic_init(obj, desired) c89atomic_store_64((atomic_ullong *)obj, (c89atomic_uint64)desired) /* atomic addition */ -#define atomic_fetch_add(obj, arg) c89atomic_fetch_add_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg) +#define atomic_fetch_add(obj, arg) c89atomic_fetch_add_64((atomic_ullong *)obj, (c89atomic_uint64)arg) /* atomic addition */ -#define atomic_fetch_add_explicit(obj, arg, order) c89atomic_fetch_add_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg, order) +#define atomic_fetch_add_explicit(obj, arg, order) c89atomic_fetch_add_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)arg, order) /* atomic subtraction */ -#define atomic_fetch_sub(obj, arg) c89atomic_fetch_sub_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg) +#define atomic_fetch_sub(obj, arg) c89atomic_fetch_sub_64((atomic_ullong *)obj, (c89atomic_uint64)arg) /* atomic subtraction */ #define atomic_fetch_sub_explicit(obj, arg, order) c89atomic_fetch_sub_explicit_64(obj, (c89atomic_uint64)arg, order) /* atomic bitwise OR */ -#define atomic_fetch_or(obj, arg) c89atomic_fetch_or_64((c89atomic_uint64 *)obj, (c89atomic_uint64 *)arg) +#define atomic_fetch_or(obj, arg) c89atomic_fetch_or_64((atomic_ullong *)obj, (atomic_ullong *)arg) /* atomic bitwise OR */ -#define atomic_fetch_or_explicit(obj, arg, order) c89atomic_fetch_or_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg, order) +#define atomic_fetch_or_explicit(obj, arg, order) c89atomic_fetch_or_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)arg, order) /* atomic bitwise exclusive OR */ #define atomic_fetch_xor(obj, arg) \ - c89atomic_fetch_xor_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg) + c89atomic_fetch_xor_64((atomic_ullong *)obj, (c89atomic_uint64)arg) /* atomic bitwise exclusive OR */ #define atomic_fetch_xor_explicit(obj, arg, order) \ - c89atomic_fetch_xor_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg, order) + c89atomic_fetch_xor_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)arg, order) /* atomic bitwise AND */ #define atomic_fetch_and(obj, arg) \ - c89atomic_fetch_and_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg) + c89atomic_fetch_and_64((atomic_ullong *)obj, (c89atomic_uint64)arg) /* atomic bitwise AND */ #define atomic_fetch_and_explicit(obj, arg, order) \ - c89atomic_fetch_and_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)arg, order) + c89atomic_fetch_and_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)arg, order) /* swaps a value with the value of an atomic object */ #define atomic_exchange(obj, desired) \ - c89atomic_exchange_64((c89atomic_uint64 *)obj, (c89atomic_uint64)desired) + c89atomic_exchange_64((atomic_ullong *)obj, (c89atomic_uint64)desired) /* swaps a value with the value of an atomic object */ #define atomic_exchange_explicit(obj, desired, order) \ - c89atomic_exchange_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)(c89atomic_uint64)desired, order) + c89atomic_exchange_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)(c89atomic_uint64)desired, order) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ -#define atomic_compare_exchange_weak(obj, expected, desired) atomic_cas((c89atomic_uint64 *)obj, expected, desired) +#define atomic_compare_exchange_weak(obj, expected, desired) atomic_cas((atomic_ullong *)obj, expected, desired) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ - c89atomic_compare_exchange_weak_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)expected, (c89atomic_uint64)desired, succ, fail) + c89atomic_compare_exchange_weak_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)expected, (c89atomic_uint64)desired, succ, fail) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ -#define atomic_compare_exchange_strong(obj, expected, desired) atomic_cas((c89atomic_uint64 *)obj, expected, desired) +#define atomic_compare_exchange_strong(obj, expected, desired) atomic_cas((atomic_ullong *)obj, expected, desired) /* swaps a value with an atomic object if the old value is what is expected, otherwise reads the old value */ #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ - c89atomic_compare_exchange_strong_explicit_64((c89atomic_uint64 *)obj, (c89atomic_uint64)expected, (c89atomic_uint64)desired, succ, fail) + c89atomic_compare_exchange_strong_explicit_64((atomic_ullong *)obj, (c89atomic_uint64)expected, (c89atomic_uint64)desired, succ, fail) #endif #endif diff --git a/rpmalloc.c b/rpmalloc.c index a587198b..f41678e9 100644 --- a/rpmalloc.c +++ b/rpmalloc.c @@ -261,20 +261,49 @@ static int _rpmalloc_shuting_down = 0; make_atomic(unsigned int, atomic32_t) make_atomic(unsigned long long, atomic64_t) -static FORCEINLINE int32_t atomic_load32(atomic32_t *src) { return c89atomic_load_explicit_32(src, memory_order_relaxed); } -static FORCEINLINE void atomic_store32(atomic32_t *dst, int32_t val) { c89atomic_store_explicit_32(dst, val, memory_order_relaxed); } -static FORCEINLINE int32_t atomic_incr32(atomic32_t *val) { return c89atomic_fetch_add_explicit_32(val, 1, memory_order_relaxed) + 1; } -static FORCEINLINE int32_t atomic_decr32(atomic32_t *val) { return c89atomic_fetch_add_explicit_32(val, -1, memory_order_relaxed) - 1; } -static FORCEINLINE int32_t atomic_add32(atomic32_t *val, int32_t add) { return c89atomic_fetch_add_explicit_32(val, add, memory_order_relaxed) + add; } -static FORCEINLINE int atomic_cas32_acquire(atomic32_t *dst, int32_t val, int32_t ref) { return c89atomic_compare_exchange_weak_explicit_32(dst, &ref, val, memory_order_acquire, memory_order_relaxed); } -static FORCEINLINE void atomic_store32_release(atomic32_t *dst, int32_t val) { c89atomic_store_explicit_32(dst, val, memory_order_release); } -static FORCEINLINE int64_t atomic_load64(atomic64_t *val) { return c89atomic_load_explicit_64((volatile c89atomic_uint64 *)val, memory_order_relaxed); } -static FORCEINLINE int64_t atomic_add64(atomic64_t *val, int64_t add) { return c89atomic_fetch_add_explicit_64((volatile c89atomic_uint64 *)val, add, memory_order_relaxed) + add; } -static FORCEINLINE void *atomic_load_ptr(atomic_ptr_t *src) { return (void *)c89atomic_load_explicit_64((volatile c89atomic_uint64 *)src, memory_order_relaxed); } -static FORCEINLINE void atomic_store_ptr(atomic_ptr_t *dst, void *val) { c89atomic_store_explicit_64((volatile c89atomic_uint64 *)dst, (c89atomic_uint64)val, memory_order_relaxed); } -static FORCEINLINE void atomic_store_ptr_release(atomic_ptr_t *dst, void *val) { c89atomic_store_explicit_64((volatile c89atomic_uint64 *)dst, (c89atomic_uint64)val, memory_order_release); } -static FORCEINLINE void *atomic_exchange_ptr_acquire(atomic_ptr_t *dst, void *val) { return (void *)c89atomic_exchange_explicit_64((volatile c89atomic_uint64 *)dst, (c89atomic_uint64)val, memory_order_acquire); } -static FORCEINLINE int atomic_cas_ptr(atomic_ptr_t *dst, void *val, void *ref) { return (int)atomic_swap((volatile c89atomic_uint64 *)dst, (c89atomic_uint64 *)&ref, (c89atomic_uint64)val); } +static FORCEINLINE int32_t atomic_load32(atomic32_t * src) { + return c89atomic_load_explicit_32(src, memory_order_relaxed); +} +static FORCEINLINE void atomic_store32(atomic32_t *dst, int32_t val) { + c89atomic_store_explicit_32(dst, val, memory_order_relaxed); +} +static FORCEINLINE int32_t atomic_incr32(atomic32_t *val) { + return c89atomic_fetch_add_explicit_32(val, 1, memory_order_relaxed) + 1; +} +static FORCEINLINE int32_t atomic_decr32(atomic32_t *val) { + return c89atomic_fetch_add_explicit_32(val, -1, memory_order_relaxed) - 1; +} +static FORCEINLINE int32_t atomic_add32(atomic32_t *val, int32_t add) { + return c89atomic_fetch_add_explicit_32(val, add, memory_order_relaxed) + add; +} +static FORCEINLINE int atomic_cas32_acquire(atomic32_t *dst, int32_t val, int32_t ref) { + return c89atomic_compare_exchange_weak_explicit_32(dst, &ref, val, memory_order_acquire, memory_order_relaxed); +} +static FORCEINLINE void atomic_store32_release(atomic32_t *dst, int32_t val) { + c89atomic_store_explicit_32(dst, val, memory_order_release); +} +static FORCEINLINE int64_t atomic_load64(atomic64_t *val) { + return c89atomic_load_explicit_64((volatile c89atomic_uint64 *)val, memory_order_relaxed); +} +static FORCEINLINE int64_t atomic_add64(atomic64_t *val, int64_t add) { + return c89atomic_fetch_add_explicit_64((volatile c89atomic_uint64 *)val, add, memory_order_relaxed) + add; +} + +static FORCEINLINE void *atomic_load_ptr(atomic_ptr_t *src) { + return (void *)atomic_load_explicit(src, memory_order_relaxed); +} +static FORCEINLINE void atomic_store_ptr(atomic_ptr_t *dst, void *val) { + atomic_store_explicit(dst, val, memory_order_relaxed); +} +static FORCEINLINE void atomic_store_ptr_release(atomic_ptr_t *dst, void *val) { + atomic_store_explicit(dst, val, memory_order_release); +} +static FORCEINLINE void *atomic_exchange_ptr_acquire(atomic_ptr_t *dst, void *val) { + return (void *)atomic_exchange_explicit(dst, val, memory_order_acquire); +} +static FORCEINLINE int atomic_cas_ptr(atomic_ptr_t *dst, void *val, void *ref) { + return (int)atomic_swap(dst, &ref, val); +} #if defined(__TINYC__) || !defined(_WIN32) int rpmalloc_tls_create(tls_t *key, tls_dtor_t dtor) { @@ -744,6 +773,8 @@ get_thread_id(void) { # if defined(__MACH__) // tpidr_el0 likely unused, always return 0 on iOS __asm__ volatile ("mrs %0, tpidrro_el0" : "=r" (tid)); +# elif defined(__TINYC__) + tid = (uintptr_t)pthread_self(); # else __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tid)); # endif @@ -789,7 +820,7 @@ _rpmalloc_spin(void) { #endif #elif defined(__x86_64__) || defined(__i386__) __asm__ volatile("pause" ::: "memory"); -#elif defined(__aarch64__) || (defined(__arm__) && __ARM_ARCH >= 7) +#elif !defined(__TINYC__) && defined(__aarch64__) || (defined(__arm__) && __ARM_ARCH >= 7) __asm__ volatile("yield" ::: "memory"); #elif defined(__powerpc__) || defined(__powerpc64__) // No idea if ever been compiled in such archs but ... as precaution @@ -1356,7 +1387,8 @@ _rpmalloc_span_finalize(heap_t * heap, size_t iclass, span_t * span, span_t * *l } //If this assert triggers you have memory leaks #if defined(ENABLE_ASSERTS) - printf("memory freed: %d, memory used: %d\n", span->list_size, span->used_count); + if (span->list_size != span->used_count) + printf("memory freed: %d, memory used: %d: heap: %p\n", span->list_size, span->used_count, free_list); #endif if (_rpmalloc_shuting_down == 0) rpmalloc_assert(span->list_size == span->used_count, "Memory leak detected");