Implement atomic operations interface

This commit is contained in:
Juliusz Sosinowicz
2023-05-17 16:22:55 +02:00
parent 5194a296e0
commit dd9edfee24
2 changed files with 77 additions and 9 deletions

View File

@@ -1155,7 +1155,49 @@ int wc_strncasecmp(const char *s1, const char *s2, size_t n)
} }
#endif /* USE_WOLF_STRNCASECMP */ #endif /* USE_WOLF_STRNCASECMP */
#if !defined(SINGLE_THREADED) && !defined(HAVE_C___ATOMIC) #ifdef WOLFSSL_ATOMIC_OPS
#ifdef HAVE_C___ATOMIC
/* Atomic ops using standard C lib */
#ifdef __cplusplus
/* C++ using direct calls to compiler built-in functions */
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
{
*c = i;
}
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
{
return __atomic_fetch_add(c, i, __ATOMIC_RELAXED);
}
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
{
return __atomic_fetch_sub(c, i, __ATOMIC_RELAXED);
}
#else
/* Default C Implementation */
WC_INLINE void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
{
atomic_init(c, i);
}
WC_INLINE int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
{
return atomic_fetch_add_explicit(c, i, memory_order_relaxed);
}
WC_INLINE int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
{
return atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
}
#endif /* __cplusplus */
#endif /* HAVE_C___ATOMIC */
#endif /* WOLFSSL_ATOMIC_OPS */
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err) void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err)
{ {
int ret = wc_InitMutex(&ref->mutex); int ret = wc_InitMutex(&ref->mutex);

View File

@@ -298,12 +298,39 @@
typedef wolfSSL_Mutex wolfSSL_RwLock; typedef wolfSSL_Mutex wolfSSL_RwLock;
#endif #endif
#ifdef HAVE_C___ATOMIC
#ifdef __cplusplus
#if defined(__GNUC__) && defined(__ATOMIC_RELAXED)
/* C++ using direct calls to compiler built-in functions */
typedef volatile int wolfSSL_Atomic_Int;
#define WOLFSSL_ATOMIC_OPS
#endif
#else
/* Default C Implementation */
#include <stdatomic.h>
typedef atomic_int wolfSSL_Atomic_Int;
#define WOLFSSL_ATOMIC_OPS
#endif
#endif
#ifdef WOLFSSL_ATOMIC_OPS
WOLFSSL_LOCAL void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i);
/* Fetch* functions return the value of the counter immediately preceding
* the effects of the function. */
WOLFSSL_LOCAL int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_LOCAL int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i);
#endif
/* Reference counting. */ /* Reference counting. */
typedef struct wolfSSL_Ref { typedef struct wolfSSL_Ref {
#if !defined(SINGLE_THREADED) && !defined(HAVE_C___ATOMIC) #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
wolfSSL_Mutex mutex; wolfSSL_Mutex mutex;
#endif #endif
#ifdef WOLFSSL_ATOMIC_OPS
wolfSSL_Atomic_Int count;
#else
int count; int count;
#endif
} wolfSSL_Ref; } wolfSSL_Ref;
#ifdef SINGLE_THREADED #ifdef SINGLE_THREADED
@@ -326,25 +353,24 @@ typedef struct wolfSSL_Ref {
*(err) = 0; \ *(err) = 0; \
} while(0) } while(0)
#elif defined(HAVE_C___ATOMIC) #elif defined(WOLFSSL_ATOMIC_OPS)
#define wolfSSL_RefInit(ref, err) \ #define wolfSSL_RefInit(ref, err) \
do { \ do { \
(ref)->count = 1; \ wolfSSL_Atomic_Int_Init(&(ref)->count, 1); \
*(err) = 0; \ *(err) = 0; \
} while(0) } while(0)
#define wolfSSL_RefFree(ref) #define wolfSSL_RefFree(ref)
#define wolfSSL_RefInc(ref, err) \ #define wolfSSL_RefInc(ref, err) \
do { \ do { \
__atomic_fetch_add(&(ref)->count, 1, \ (void)wolfSSL_Atomic_Int_FetchAdd(&(ref)->count, 1); \
__ATOMIC_RELAXED); \
*(err) = 0; \ *(err) = 0; \
} while(0) } while(0)
#define wolfSSL_RefDec(ref, isZero, err) \ #define wolfSSL_RefDec(ref, isZero, err) \
do { \ do { \
__atomic_fetch_sub(&(ref)->count, 1, \ int __prev = wolfSSL_Atomic_Int_FetchSub(&(ref)->count, 1); \
__ATOMIC_RELAXED); \ /* __prev holds the value of count before subtracting 1 */ \
*(isZero) = ((ref)->count == 0); \ *(isZero) = (__prev == 1); \
*(err) = 0; \ *(err) = 0; \
} while(0) } while(0)