Skip to content

Commit dd9edfe

Browse files
committed
Implement atomic operations interface
1 parent 5194a29 commit dd9edfe

2 files changed

Lines changed: 77 additions & 9 deletions

File tree

wolfcrypt/src/wc_port.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,49 @@ 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+
WC_INLINE void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i)
1181+
{
1182+
atomic_init(c, i);
1183+
}
1184+
1185+
WC_INLINE 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+
WC_INLINE 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+
#endif /* HAVE_C___ATOMIC */
1197+
1198+
#endif /* WOLFSSL_ATOMIC_OPS */
1199+
1200+
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
11591201
void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err)
11601202
{
11611203
int ret = wc_InitMutex(&ref->mutex);

wolfssl/wolfcrypt/wc_port.h

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,39 @@
298298
typedef wolfSSL_Mutex wolfSSL_RwLock;
299299
#endif
300300

301+
#ifdef HAVE_C___ATOMIC
302+
#ifdef __cplusplus
303+
#if defined(__GNUC__) && defined(__ATOMIC_RELAXED)
304+
/* C++ using direct calls to compiler built-in functions */
305+
typedef volatile int wolfSSL_Atomic_Int;
306+
#define WOLFSSL_ATOMIC_OPS
307+
#endif
308+
#else
309+
/* Default C Implementation */
310+
#include <stdatomic.h>
311+
typedef atomic_int wolfSSL_Atomic_Int;
312+
#define WOLFSSL_ATOMIC_OPS
313+
#endif
314+
#endif
315+
316+
#ifdef WOLFSSL_ATOMIC_OPS
317+
WOLFSSL_LOCAL void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i);
318+
/* Fetch* functions return the value of the counter immediately preceding
319+
* the effects of the function. */
320+
WOLFSSL_LOCAL int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i);
321+
WOLFSSL_LOCAL int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i);
322+
#endif
323+
301324
/* Reference counting. */
302325
typedef struct wolfSSL_Ref {
303-
#if !defined(SINGLE_THREADED) && !defined(HAVE_C___ATOMIC)
326+
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
304327
wolfSSL_Mutex mutex;
305328
#endif
329+
#ifdef WOLFSSL_ATOMIC_OPS
330+
wolfSSL_Atomic_Int count;
331+
#else
306332
int count;
333+
#endif
307334
} wolfSSL_Ref;
308335

309336
#ifdef SINGLE_THREADED
@@ -326,25 +353,24 @@ typedef struct wolfSSL_Ref {
326353
*(err) = 0; \
327354
} while(0)
328355

329-
#elif defined(HAVE_C___ATOMIC)
356+
#elif defined(WOLFSSL_ATOMIC_OPS)
330357

331358
#define wolfSSL_RefInit(ref, err) \
332359
do { \
333-
(ref)->count = 1; \
360+
wolfSSL_Atomic_Int_Init(&(ref)->count, 1); \
334361
*(err) = 0; \
335362
} while(0)
336363
#define wolfSSL_RefFree(ref)
337364
#define wolfSSL_RefInc(ref, err) \
338365
do { \
339-
__atomic_fetch_add(&(ref)->count, 1, \
340-
__ATOMIC_RELAXED); \
366+
(void)wolfSSL_Atomic_Int_FetchAdd(&(ref)->count, 1); \
341367
*(err) = 0; \
342368
} while(0)
343369
#define wolfSSL_RefDec(ref, isZero, err) \
344370
do { \
345-
__atomic_fetch_sub(&(ref)->count, 1, \
346-
__ATOMIC_RELAXED); \
347-
*(isZero) = ((ref)->count == 0); \
371+
int __prev = wolfSSL_Atomic_Int_FetchSub(&(ref)->count, 1); \
372+
/* __prev holds the value of count before subtracting 1 */ \
373+
*(isZero) = (__prev == 1); \
348374
*(err) = 0; \
349375
} while(0)
350376

0 commit comments

Comments
 (0)