298298 typedef wolfSSL_Mutex wolfSSL_RwLock ;
299299#endif
300300
301+ #ifndef WOLFSSL_NO_ATOMICS
302+ #ifdef HAVE_C___ATOMIC
303+ #ifdef __cplusplus
304+ #if defined(__GNUC__ ) && defined(__ATOMIC_RELAXED )
305+ /* C++ using direct calls to compiler built-in functions */
306+ typedef volatile int wolfSSL_Atomic_Int ;
307+ #define WOLFSSL_ATOMIC_OPS
308+ #endif
309+ #else
310+ /* Default C Implementation */
311+ #include <stdatomic.h>
312+ typedef atomic_int wolfSSL_Atomic_Int ;
313+ #define WOLFSSL_ATOMIC_OPS
314+ #endif
315+ #elif defined(_MSC_VER )
316+ /* Use MSVC compiler intrinsics for atomic ops */
317+ #include <intrin.h>
318+ typedef volatile long wolfSSL_Atomic_Int ;
319+ #define WOLFSSL_ATOMIC_OPS
320+ #endif
321+ #endif /* WOLFSSL_NO_ATOMICS */
322+
323+ #ifdef WOLFSSL_ATOMIC_OPS
324+ WOLFSSL_LOCAL void wolfSSL_Atomic_Int_Init (wolfSSL_Atomic_Int * c , int i );
325+ /* Fetch* functions return the value of the counter immediately preceding
326+ * the effects of the function. */
327+ WOLFSSL_LOCAL int wolfSSL_Atomic_Int_FetchAdd (wolfSSL_Atomic_Int * c , int i );
328+ WOLFSSL_LOCAL int wolfSSL_Atomic_Int_FetchSub (wolfSSL_Atomic_Int * c , int i );
329+ #endif
330+
301331/* Reference counting. */
302332typedef struct wolfSSL_Ref {
303- #if !defined(SINGLE_THREADED ) && !defined(HAVE_C___ATOMIC )
333+ #if !defined(SINGLE_THREADED ) && !defined(WOLFSSL_ATOMIC_OPS )
304334 wolfSSL_Mutex mutex ;
305335#endif
336+ #ifdef WOLFSSL_ATOMIC_OPS
337+ wolfSSL_Atomic_Int count ;
338+ #else
306339 int count ;
340+ #endif
307341} wolfSSL_Ref ;
308342
309343#ifdef SINGLE_THREADED
@@ -326,25 +360,24 @@ typedef struct wolfSSL_Ref {
326360 *(err) = 0; \
327361 } while(0)
328362
329- #elif defined(HAVE_C___ATOMIC )
363+ #elif defined(WOLFSSL_ATOMIC_OPS )
330364
331365#define wolfSSL_RefInit (ref , err ) \
332366 do { \
333- ( ref)->count = 1; \
367+ wolfSSL_Atomic_Int_Init(&( ref)->count, 1); \
334368 *(err) = 0; \
335369 } while(0)
336370#define wolfSSL_RefFree (ref )
337371#define wolfSSL_RefInc (ref , err ) \
338372 do { \
339- __atomic_fetch_add(&(ref)->count, 1, \
340- __ATOMIC_RELAXED); \
373+ (void)wolfSSL_Atomic_Int_FetchAdd(&(ref)->count, 1); \
341374 *(err) = 0; \
342375 } while(0)
343376#define wolfSSL_RefDec (ref , isZero , err ) \
344377 do { \
345- __atomic_fetch_sub (&(ref)->count, 1, \
346- __ATOMIC_RELAXED); \
347- *(isZero) = ((ref)->count == 0 ); \
378+ int __prev = wolfSSL_Atomic_Int_FetchSub (&(ref)->count, 1); \
379+ /* __prev holds the value of count before subtracting 1 */ \
380+ * (isZero ) = (__prev == 1 ); \
348381 * (err ) = 0 ; \
349382 } while (0 )
350383
0 commit comments