diff --git a/include/volk/volk_prefs.h b/include/volk/volk_prefs.h index 3aa8bc54..d1231799 100644 --- a/include/volk/volk_prefs.h +++ b/include/volk/volk_prefs.h @@ -22,6 +22,12 @@ typedef struct volk_arch_pref { char impl_u[128]; // best unaligned impl } volk_arch_pref_t; + +VOLK_API void volk_initialize_preferences(); +VOLK_API void volk_free_preferences(); +VOLK_API const size_t volk_get_num_arch_prefs(); +VOLK_API const volk_arch_pref_t* volk_get_arch_prefs(); + //////////////////////////////////////////////////////////////////////// // get path to volk_config profiling info; second arguments specifies // if config file should be tested on existence for reading. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a27be22b..4b9b0c99 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -560,6 +560,7 @@ if(ORC_FOUND) endif() if(NOT MSVC) target_link_libraries(volk PUBLIC m) + target_link_libraries(volk PRIVATE pthread) endif() set_target_properties(volk PROPERTIES VERSION ${VERSION}) set_target_properties(volk PROPERTIES SOVERSION ${SOVERSION}) diff --git a/lib/volk_prefs.c b/lib/volk_prefs.c index 2ff989e3..47c1aebf 100644 --- a/lib/volk_prefs.c +++ b/lib/volk_prefs.c @@ -18,6 +18,9 @@ #else #include #endif +#ifndef __STDC_NO_THREADS__ +#include +#endif #include void volk_get_config_path(char* path, bool read) @@ -72,6 +75,76 @@ void volk_get_config_path(char* path, bool read) return; } + +static struct volk_preferences { + volk_arch_pref_t* volk_arch_prefs; + size_t n_arch_prefs; + int initialized; +#ifndef __STDC_NO_THREADS__ + mtx_t mutex; +#endif +} volk_preferences; + +#ifndef __STDC_NO_THREADS__ +void init_struct_mutex(void) +{ + if (mtx_init(&volk_preferences.mutex, mtx_plain) != thrd_success) { + printf("\n mutex init failed\n"); + } +} + +static once_flag mutex_init_once_flag = ONCE_FLAG_INIT; +void initialize_mutex() { call_once(&mutex_init_once_flag, init_struct_mutex); } +#endif + +void volk_initialize_preferences() +{ +#ifndef __STDC_NO_THREADS__ + initialize_mutex(); + mtx_lock(&volk_preferences.mutex); +#endif + if (!volk_preferences.initialized) { + volk_preferences.n_arch_prefs = + volk_load_preferences(&volk_preferences.volk_arch_prefs); + volk_preferences.initialized = 1; + } +#ifndef __STDC_NO_THREADS__ + mtx_unlock(&volk_preferences.mutex); +#endif +} + + +void volk_free_preferences() +{ +#ifndef __STDC_NO_THREADS__ + initialize_mutex(); + mtx_lock(&volk_preferences.mutex); +#endif + if (volk_preferences.initialized) { + free(volk_preferences.volk_arch_prefs); + volk_preferences.n_arch_prefs = 0; + volk_preferences.initialized = 0; + } +#ifndef __STDC_NO_THREADS__ + mtx_unlock(&volk_preferences.mutex); +#endif +} + + +const size_t volk_get_num_arch_prefs() +{ + volk_initialize_preferences(); + return volk_preferences.n_arch_prefs; +} + + +const volk_arch_pref_t* volk_get_arch_prefs() +{ + volk_initialize_preferences(); + return volk_preferences.volk_arch_prefs; +} + + size_t volk_load_preferences(volk_arch_pref_t** prefs_res) { FILE* config_file; diff --git a/lib/volk_rank_archs.c b/lib/volk_rank_archs.c index 750fe54b..f5521268 100644 --- a/lib/volk_rank_archs.c +++ b/lib/volk_rank_archs.c @@ -41,13 +41,9 @@ int volk_rank_archs(const char* kern_name, // name of the kernel to rank ) { size_t i; - static volk_arch_pref_t* volk_arch_prefs; - static size_t n_arch_prefs = 0; - static int prefs_loaded = 0; - if (!prefs_loaded) { - n_arch_prefs = volk_load_preferences(&volk_arch_prefs); - prefs_loaded = 1; - } + + const volk_arch_pref_t* volk_arch_prefs = volk_get_arch_prefs(); + const size_t n_arch_prefs = volk_get_num_arch_prefs(); // If we've defined VOLK_GENERIC to be anything, always return the // 'generic' kernel. Used in GR's QA code.