Skip to content

Commit

Permalink
Use Thread Local Storage for warray buffer
Browse files Browse the repository at this point in the history
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
  • Loading branch information
sjaeckel committed Mar 29, 2024
1 parent 334465d commit 33a9d0d
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 173 deletions.
20 changes: 11 additions & 9 deletions demo/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2502,20 +2502,24 @@ struct thread_info {
int ret;
};

static void *run_pthread(void *arg)
static void run(struct thread_info *tinfo)
{
struct thread_info *tinfo = arg;

tinfo->ret = tinfo->t->fn();

if (mp_warray_free() == -2)
tinfo->ret = EXIT_FAILURE;
}

static void *run_pthread(void *arg)
{
run(arg);

return arg;
}

static unsigned long run_msvc(void *arg)
{
struct thread_info *tinfo = arg;

tinfo->ret = tinfo->t->fn();
run(arg);

return 0;
}
Expand Down Expand Up @@ -2609,7 +2613,6 @@ static int unit_tests(int argc, char **argv)
};
struct thread_info test_threads[sizeof(test)/sizeof(test[0])], *res;
unsigned long i, ok, fail, nop;
size_t n_threads = MP_HAS(MULTI_THREADED) ? sizeof(test) / sizeof(test[0]) : 1;
uint64_t t;
int j;
ok = fail = nop = 0;
Expand All @@ -2620,8 +2623,7 @@ static int unit_tests(int argc, char **argv)
mp_rand_source(s_mp_rand_jenkins);

if (MP_HAS(MP_SMALL_STACK_SIZE)) {
printf("Small-stack enabled with %zu warray buffers\n\n", n_threads);
DO(mp_warray_init(n_threads, 1));
printf("Small-stack enabled\n\n");
}

if (MP_HAS(MULTI_THREADED)) {
Expand Down
18 changes: 6 additions & 12 deletions mp_warray_free.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@ MP_STATIC_ASSERT(warray_free_sz_does_not_overflow, (sizeof(mp_word) * MP_WARRAY)
static int s_warray_free(void)
{
int ret = 0;
size_t n;
for (n = 0; n < s_mp_warray.allocated; ++n) {
if (s_mp_warray.l_used[n].warray) {
ret = -2;
goto ERR_OUT;
}
if (s_mp_warray.w_used)
return -2;
if (s_mp_warray.w_free) {
s_mp_zero_buf(s_mp_warray.w_free, sizeof(mp_word) * MP_WARRAY);
MP_FREE(s_mp_warray.w_free, sizeof(mp_word) * MP_WARRAY);
s_mp_warray.w_free = NULL;
}
for (n = 0; n < s_mp_warray.allocated; ++n) {
MP_FREE(s_mp_warray.l_free[n].warray, sizeof(mp_word) * MP_WARRAY);
s_mp_warray.l_free[n].warray = NULL;
}
s_mp_warray_free(s_mp_warray.usable);
ERR_OUT:
return ret;
}

Expand Down
46 changes: 0 additions & 46 deletions mp_warray_init.c

This file was deleted.

43 changes: 0 additions & 43 deletions s_mp_cmpexch_n.c

This file was deleted.

2 changes: 1 addition & 1 deletion s_mp_warray.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */

st_warray s_mp_warray;
mp_thread st_warray s_mp_warray = { 0 };

#endif
17 changes: 0 additions & 17 deletions s_mp_warray_free.c

This file was deleted.

34 changes: 7 additions & 27 deletions s_mp_warray_get.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,14 @@

void *s_mp_warray_get(void)
{
void *ret = NULL;
size_t n;
if (s_mp_warray.usable == 0) {
if (mp_warray_init(1, false) != MP_OKAY)
return NULL;
if (s_mp_warray.w_used)
return NULL;
if (s_mp_warray.w_free == NULL) {
s_mp_warray.w_free = MP_CALLOC(MP_WARRAY, sizeof(mp_word));
}
for (n = 0; n < s_mp_warray.allocated;) {
if (s_mp_warray.l_free[n].warray == NULL) {
n++;
continue;
}
ret = s_mp_warray.l_free[n].warray;
if (s_mp_cmpexch_n(&s_mp_warray.l_free[n].warray, &ret, NULL)) {
s_mp_warray.l_used[n].warray = ret;
goto LBL_OUT;
}
/* restart from the beginning if we missed a potential slot */
n = 0;
}
ret = NULL;
if (s_mp_warray.allocated + 1 > s_mp_warray.usable)
goto LBL_OUT;
ret = MP_CALLOC(MP_WARRAY, sizeof(mp_word));
if (ret != NULL)
s_mp_warray.l_used[s_mp_warray.allocated++].warray = ret;

LBL_OUT:
return ret;
s_mp_warray.w_used = s_mp_warray.w_free;
s_mp_warray.w_free = NULL;
return s_mp_warray.w_used;
}

#endif
12 changes: 4 additions & 8 deletions s_mp_warray_put.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@

void s_mp_warray_put(void *w)
{
size_t n, allocated = s_mp_warray.allocated;
for (n = 0; n < allocated; ++n) {
if (s_mp_warray.l_used[n].warray == w) {
s_mp_warray.l_used[n].warray = NULL;
s_mp_warray.l_free[n].warray = w;
break;
}
}
if (s_mp_warray.w_free || s_mp_warray.w_used != w)
return;
s_mp_warray.w_free = w;
s_mp_warray.w_used = NULL;
}

#endif
1 change: 0 additions & 1 deletion tommath.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,6 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR;
mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR;
#endif

mp_err mp_warray_init(size_t n_alloc, bool preallocate);
int mp_warray_free(void);

#define mp_to_binary(M, S, N) mp_to_radix((M), (S), (N), NULL, 2)
Expand Down
17 changes: 8 additions & 9 deletions tommath_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,6 @@ MP_PRIVATE mp_err s_mp_radix_size_overestimate(const mp_int *a, const int radix,
MP_PRIVATE mp_err s_mp_fp_log(const mp_int *a, mp_int *c) MP_WUR;
MP_PRIVATE mp_err s_mp_fp_log_d(const mp_int *a, mp_word *c) MP_WUR;

MP_PRIVATE bool s_mp_cmpexch_n(void **ptr, void **expected, void *desired);

#ifdef MP_SMALL_STACK_SIZE
#define MP_SMALL_STACK_SIZE_C
#define MP_ALLOC_WARRAY(name) *name = s_mp_warray_get()
Expand All @@ -247,19 +245,20 @@ MP_PRIVATE bool s_mp_cmpexch_n(void **ptr, void **expected, void *desired);
#define MP_CHECK_WARRAY(name)
#endif

struct warray {
void *warray;
};
#if defined(_MSC_VER)
#define mp_thread __declspec(thread)
#elif defined(__GNUC__)
#define mp_thread __thread
#endif

typedef struct {
struct warray *l_free, *l_used;
size_t allocated, usable;
void *w_free, *w_used;
} st_warray;

extern MP_PRIVATE st_warray s_mp_warray;
extern MP_PRIVATE mp_thread st_warray s_mp_warray;

MP_PRIVATE void *s_mp_warray_get(void);
MP_PRIVATE void s_mp_warray_put(void *w);
MP_PRIVATE void s_mp_warray_free(size_t n);

#define MP_RADIX_MAP_REVERSE_SIZE 80u
extern MP_PRIVATE const char s_mp_radix_map[];
Expand Down

0 comments on commit 33a9d0d

Please sign in to comment.