Skip to content

Commit 235dc95

Browse files
Merge pull request #6420 from julek-wolfssl/atomic-use-macro
Implement atomic operations interface
2 parents 8b9e138 + 4666362 commit 235dc95

2 files changed

Lines changed: 102 additions & 9 deletions

File tree

wolfcrypt/src/wc_port.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,67 @@ int wc_strncasecmp(const char *s1, const char *s2, size_t n)
11551155
}
11561156
#endif /* USE_WOLF_STRNCASECMP */
11571157

1158-
#if !defined(SINGLE_THREADED) && !defined(HAVE_C___ATOMIC)
1158+
#ifdef WOLFSSL_ATOMIC_OPS
1159+
1160+
#ifdef HAVE_C___ATOMIC
1161+
/* Atomic ops using standard C lib */
1162+
#ifdef __cplusplus
1163+
/* C++ using direct calls to compiler built-in functions */
1164+
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1165+
{
1166+
*c = i;
1167+
}
1168+
1169+
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1170+
{
1171+
return __atomic_fetch_add(c, i, __ATOMIC_RELAXED);
1172+
}
1173+
1174+
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1175+
{
1176+
return __atomic_fetch_sub(c, i, __ATOMIC_RELAXED);
1177+
}
1178+
#else
1179+
/* Default C Implementation */
1180+
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1181+
{
1182+
atomic_init(c, i);
1183+
}
1184+
1185+
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1186+
{
1187+
return atomic_fetch_add_explicit(c, i, memory_order_relaxed);
1188+
}
1189+
1190+
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1191+
{
1192+
return atomic_fetch_sub_explicit(c, i, memory_order_relaxed);
1193+
}
1194+
#endif /* __cplusplus */
1195+
1196+
#elif defined(_MSC_VER)
1197+
1198+
/* Default C Implementation */
1199+
void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1200+
{
1201+
*c = i;
1202+
}
1203+
1204+
int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i)
1205+
{
1206+
return (int)_InterlockedExchangeAdd(c, (long)i);
1207+
}
1208+
1209+
int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)
1210+
{
1211+
return (int)_InterlockedExchangeAdd(c, (long)-i);
1212+
}
1213+
1214+
#endif
1215+
1216+
#endif /* WOLFSSL_ATOMIC_OPS */
1217+
1218+
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
11591219
void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err)
11601220
{
11611221
int ret = wc_InitMutex(&ref->mutex);

wolfssl/wolfcrypt/wc_port.h

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,46 @@
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. */
302332
typedef 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

Comments
 (0)