From dd9edfee24fd9f51eb1977d210199e1e56868651 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 17 May 2023 16:22:55 +0200 Subject: [PATCH 1/2] Implement atomic operations interface --- wolfcrypt/src/wc_port.c | 44 ++++++++++++++++++++++++++++++++++++- wolfssl/wolfcrypt/wc_port.h | 42 ++++++++++++++++++++++++++++------- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index b6736e501..e9ce63760 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1155,7 +1155,49 @@ 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 */ +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) { int ret = wc_InitMutex(&ref->mutex); diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index c44ce4a2e..635ed59fd 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -298,12 +298,39 @@ typedef wolfSSL_Mutex wolfSSL_RwLock; #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 + 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. */ 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 +353,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) From 466636214fb5d86b27d1114abc665162d81ff366 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 18 May 2023 12:06:54 +0200 Subject: [PATCH 2/2] Add MSVC atomics --- wolfcrypt/src/wc_port.c | 26 ++++++++++++++++++++++---- wolfssl/wolfcrypt/wc_port.h | 7 +++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index e9ce63760..c789ae2e4 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1177,23 +1177,41 @@ int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i) } #else /* Default C Implementation */ -WC_INLINE void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i) +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) +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) +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 */ +#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 */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 635ed59fd..1737c3f63 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -298,6 +298,7 @@ typedef wolfSSL_Mutex wolfSSL_RwLock; #endif +#ifndef WOLFSSL_NO_ATOMICS #ifdef HAVE_C___ATOMIC #ifdef __cplusplus #if defined(__GNUC__) && defined(__ATOMIC_RELAXED) @@ -311,7 +312,13 @@ typedef atomic_int wolfSSL_Atomic_Int; #define WOLFSSL_ATOMIC_OPS #endif +#elif defined(_MSC_VER) + /* Use MSVC compiler intrinsics for atomic ops */ + #include + 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);