forked from wolfSSL/wolfssl
Merge pull request #6420 from julek-wolfssl/atomic-use-macro
Implement atomic operations interface
This commit is contained in:
@ -1155,7 +1155,67 @@ int wc_strncasecmp(const char *s1, const char *s2, size_t n)
|
||||
}
|
||||
#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 */
|
||||
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
|
||||
{
|
||||
atomic_init(c, i);
|
||||
}
|
||||
|
||||
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
|
||||
{
|
||||
return atomic_fetch_add_explicit(c, i, memory_order_relaxed);
|
||||
}
|
||||
|
||||
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
|
||||
{
|
||||
return atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
/* Default C Implementation */
|
||||
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 (int)_InterlockedExchangeAdd(c, (long)i);
|
||||
}
|
||||
|
||||
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
|
||||
{
|
||||
return (int)_InterlockedExchangeAdd(c, (long)-i);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_ATOMIC_OPS */
|
||||
|
||||
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
|
||||
void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err)
|
||||
{
|
||||
int ret = wc_InitMutex(&ref->mutex);
|
||||
|
@ -298,12 +298,46 @@
|
||||
typedef wolfSSL_Mutex wolfSSL_RwLock;
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_NO_ATOMICS
|
||||
#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
|
||||
#elif defined(_MSC_VER)
|
||||
/* Use MSVC compiler intrinsics for atomic ops */
|
||||
#include <intrin.h>
|
||||
typedef volatile long wolfSSL_Atomic_Int;
|
||||
#define WOLFSSL_ATOMIC_OPS
|
||||
#endif
|
||||
#endif /* WOLFSSL_NO_ATOMICS */
|
||||
|
||||
#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. */
|
||||
typedef struct wolfSSL_Ref {
|
||||
#if !defined(SINGLE_THREADED) && !defined(HAVE_C___ATOMIC)
|
||||
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
|
||||
wolfSSL_Mutex mutex;
|
||||
#endif
|
||||
#ifdef WOLFSSL_ATOMIC_OPS
|
||||
wolfSSL_Atomic_Int count;
|
||||
#else
|
||||
int count;
|
||||
#endif
|
||||
} wolfSSL_Ref;
|
||||
|
||||
#ifdef SINGLE_THREADED
|
||||
@ -326,25 +360,24 @@ typedef struct wolfSSL_Ref {
|
||||
*(err) = 0; \
|
||||
} while(0)
|
||||
|
||||
#elif defined(HAVE_C___ATOMIC)
|
||||
#elif defined(WOLFSSL_ATOMIC_OPS)
|
||||
|
||||
#define wolfSSL_RefInit(ref, err) \
|
||||
do { \
|
||||
(ref)->count = 1; \
|
||||
wolfSSL_Atomic_Int_Init(&(ref)->count, 1); \
|
||||
*(err) = 0; \
|
||||
} while(0)
|
||||
#define wolfSSL_RefFree(ref)
|
||||
#define wolfSSL_RefInc(ref, err) \
|
||||
do { \
|
||||
__atomic_fetch_add(&(ref)->count, 1, \
|
||||
__ATOMIC_RELAXED); \
|
||||
(void)wolfSSL_Atomic_Int_FetchAdd(&(ref)->count, 1); \
|
||||
*(err) = 0; \
|
||||
} while(0)
|
||||
#define wolfSSL_RefDec(ref, isZero, err) \
|
||||
do { \
|
||||
__atomic_fetch_sub(&(ref)->count, 1, \
|
||||
__ATOMIC_RELAXED); \
|
||||
*(isZero) = ((ref)->count == 0); \
|
||||
int __prev = wolfSSL_Atomic_Int_FetchSub(&(ref)->count, 1); \
|
||||
/* __prev holds the value of count before subtracting 1 */ \
|
||||
*(isZero) = (__prev == 1); \
|
||||
*(err) = 0; \
|
||||
} while(0)
|
||||
|
||||
|
Reference in New Issue
Block a user