Skip to content

Commit b0bd6dc

Browse files
committed
Add s_mp_cmpexch_n()
To be able to support this for MSVC as well, we have to move this into a separate private API function. Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 15f7aa2 commit b0bd6dc

File tree

4 files changed

+51
-5
lines changed

4 files changed

+51
-5
lines changed

s_mp_cmpexch_n.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "tommath_private.h"
2+
#ifdef S_MP_CMPEXCH_N_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4+
/* SPDX-License-Identifier: Unlicense */
5+
6+
#ifdef __GNUC__
7+
#define S_CMPEXCH_N_GCC_C
8+
bool s_cmpexch_n_gcc(void **ptr, void **expected, void *desired)
9+
{
10+
return __atomic_compare_exchange_n(ptr, expected, desired, true, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
11+
}
12+
#endif
13+
14+
#ifdef _MSC_VER
15+
#define S_CMPEXCH_N_MSVC_C
16+
17+
#ifndef _WIN32_WINNT
18+
#define _WIN32_WINNT 0x0501
19+
#endif
20+
#ifndef WINVER
21+
#define WINVER 0x0501
22+
#endif
23+
24+
#define WIN32_LEAN_AND_MEAN
25+
#include <windows.h>
26+
27+
bool s_cmpexch_n_msvc(void **ptr, void **expected, void *desired)
28+
{
29+
return InterlockedCompareExchangePointer(ptr, *(expected), desired) == desired;
30+
}
31+
#endif
32+
33+
bool s_cmpexch_n_gcc(void **ptr, void **expected, void *desired);
34+
bool s_cmpexch_n_msvc(void **ptr, void **expected, void *desired);
35+
36+
bool s_mp_cmpexch_n(void **ptr, void **expected, void *desired)
37+
{
38+
if (MP_HAS(S_CMPEXCH_N_GCC)) return s_cmpexch_n_gcc(ptr, expected, desired);
39+
if (MP_HAS(S_CMPEXCH_N_MSVC)) return s_cmpexch_n_msvc(ptr, expected, desired);
40+
return false;
41+
}
42+
43+
#endif

s_mp_warray_get.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void *s_mp_warray_get(void)
1515
if (s_mp_warray.l_free[n].warray == NULL)
1616
continue;
1717
ret = s_mp_warray.l_free[n].warray;
18-
if (MP_CMPEXCH(&s_mp_warray.l_free[n].warray, &ret, NULL)) {
18+
if (s_mp_cmpexch_n(&s_mp_warray.l_free[n].warray, &ret, NULL)) {
1919
s_mp_warray.l_used[n].warray = ret;
2020
goto LBL_OUT;
2121
}

tommath_class.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
# define MP_XOR_C
137137
# define MP_ZERO_C
138138
# define S_MP_ADD_C
139+
# define S_MP_CMPEXCH_N_C
139140
# define S_MP_COPY_DIGS_C
140141
# define S_MP_DIV_3_C
141142
# define S_MP_DIV_RECURSIVE_C
@@ -986,6 +987,9 @@
986987
# define S_MP_ZERO_DIGS_C
987988
#endif
988989

990+
#if defined(S_MP_CMPEXCH_N_C)
991+
#endif
992+
989993
#if defined(S_MP_COPY_DIGS_C)
990994
#endif
991995

@@ -1309,6 +1313,7 @@
13091313

13101314
#if defined(S_MP_WARRAY_GET_C)
13111315
# define MP_WARRAY_INIT_C
1316+
# define S_MP_CMPEXCH_N_C
13121317
#endif
13131318

13141319
#if defined(S_MP_WARRAY_PUT_C)

tommath_private.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,6 @@ extern void *MP_CALLOC(size_t nmemb, size_t size);
104104
extern void MP_FREE(void *mem, size_t size);
105105
#endif
106106

107-
#ifndef MP_CMPEXCH
108-
#define MP_CMPEXCH(ptr, expected, desired) __atomic_compare_exchange_n(ptr, expected, desired, true, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)
109-
#endif
110-
111107
/* feature detection macro */
112108
#ifdef _MSC_VER
113109
/* Prevent false positive: not enough arguments for function-like macro invocation */
@@ -238,6 +234,8 @@ MP_PRIVATE mp_err s_mp_radix_size_overestimate(const mp_int *a, const int radix,
238234
MP_PRIVATE mp_err s_mp_fp_log(const mp_int *a, mp_int *c) MP_WUR;
239235
MP_PRIVATE mp_err s_mp_fp_log_d(const mp_int *a, mp_word *c) MP_WUR;
240236

237+
MP_PRIVATE bool s_mp_cmpexch_n(void **ptr, void **expected, void *desired);
238+
241239
#ifdef MP_SMALL_STACK_SIZE
242240
#define MP_SMALL_STACK_SIZE_C
243241
#define MP_ALLOC_WARRAY(name) *name = s_mp_warray_get()

0 commit comments

Comments
 (0)