Skip to content

Commit e355e59

Browse files
committed
threadsafe: Load preferences threadsafe
Instead of static variables in a function, we store preferences in a struct and use an `atomic_int` to prevent any more than one thread from loading preferences. Fixes #440 Signed-off-by: Johannes Demel <[email protected]>
1 parent d5b317c commit e355e59

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

include/volk/volk_prefs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ typedef struct volk_arch_pref {
2222
char impl_u[128]; // best unaligned impl
2323
} volk_arch_pref_t;
2424

25+
26+
VOLK_API void volk_initialize_preferences();
27+
VOLK_API void volk_free_preferences();
28+
VOLK_API const size_t volk_get_num_arch_prefs();
29+
VOLK_API const volk_arch_pref_t* volk_get_arch_prefs();
30+
2531
////////////////////////////////////////////////////////////////////////
2632
// get path to volk_config profiling info; second arguments specifies
2733
// if config file should be tested on existence for reading.

lib/volk_prefs.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#else
1919
#include <unistd.h>
2020
#endif
21+
#include <stdatomic.h>
2122
#include <volk/volk_prefs.h>
2223

2324
void volk_get_config_path(char* path, bool read)
@@ -72,6 +73,48 @@ void volk_get_config_path(char* path, bool read)
7273
return;
7374
}
7475

76+
77+
static struct volk_preferences {
78+
volk_arch_pref_t* volk_arch_prefs;
79+
size_t n_arch_prefs;
80+
atomic_int initialized;
81+
82+
} volk_preferences;
83+
84+
85+
void volk_initialize_preferences()
86+
{
87+
if (!atomic_fetch_and(&volk_preferences.initialized, 1)) {
88+
volk_preferences.n_arch_prefs =
89+
volk_load_preferences(&volk_preferences.volk_arch_prefs);
90+
}
91+
}
92+
93+
94+
void volk_free_preferences()
95+
{
96+
if (volk_preferences.initialized) {
97+
free(volk_preferences.volk_arch_prefs);
98+
volk_preferences.n_arch_prefs = 0;
99+
volk_preferences.initialized = 0;
100+
}
101+
}
102+
103+
104+
const size_t volk_get_num_arch_prefs()
105+
{
106+
volk_initialize_preferences();
107+
return volk_preferences.n_arch_prefs;
108+
}
109+
110+
111+
const volk_arch_pref_t* volk_get_arch_prefs()
112+
{
113+
volk_initialize_preferences();
114+
return volk_preferences.volk_arch_prefs;
115+
}
116+
117+
75118
size_t volk_load_preferences(volk_arch_pref_t** prefs_res)
76119
{
77120
FILE* config_file;

lib/volk_rank_archs.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,9 @@ int volk_rank_archs(const char* kern_name, // name of the kernel to rank
4141
)
4242
{
4343
size_t i;
44-
static volk_arch_pref_t* volk_arch_prefs;
45-
static size_t n_arch_prefs = 0;
46-
static int prefs_loaded = 0;
47-
if (!prefs_loaded) {
48-
n_arch_prefs = volk_load_preferences(&volk_arch_prefs);
49-
prefs_loaded = 1;
50-
}
44+
45+
const volk_arch_pref_t* volk_arch_prefs = volk_get_arch_prefs();
46+
const size_t n_arch_prefs = volk_get_num_arch_prefs();
5147

5248
// If we've defined VOLK_GENERIC to be anything, always return the
5349
// 'generic' kernel. Used in GR's QA code.

0 commit comments

Comments
 (0)