diff --git a/CMakeLists.txt b/CMakeLists.txt index ce7eb35e..36c40cdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,37 @@ if(NOT DEFAULT_RADIX) endif() cmake_print_variables(FIXED_POINT DEFAULT_RADIX) +option(PS_THREAD_LOCAL_RNG "Use thread-local storage for random number generator" ON) +if(PS_THREAD_LOCAL_RNG) + # Test for thread-local storage support + include(CheckCSourceCompiles) + check_c_source_compiles(" + _Thread_local int x; + int main() { x = 42; return 0; } + " HAVE_C11_THREAD_LOCAL) + + check_c_source_compiles(" + __thread int x; + int main() { x = 42; return 0; } + " HAVE_GCC_THREAD_LOCAL) + + check_c_source_compiles(" + __declspec(thread) int x; + int main() { x = 42; return 0; } + " HAVE_MSVC_THREAD_LOCAL) + + if(HAVE_C11_THREAD_LOCAL OR HAVE_GCC_THREAD_LOCAL OR HAVE_MSVC_THREAD_LOCAL) + add_definitions(-DPS_USE_THREAD_LOCAL_RNG) + message(STATUS "Thread-local storage support: ENABLED") + else() + message(WARNING "Thread-local storage not supported on this compiler. Disabling PS_THREAD_LOCAL_RNG") + set(PS_THREAD_LOCAL_RNG OFF) + endif() +else() + message(STATUS "Thread-local storage support: DISABLED") +endif() +cmake_print_variables(PS_THREAD_LOCAL_RNG) + # Maybe not a great idea, but it does work on both Windows and Linux set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/config.h.in b/config.h.in index 46d2ff00..1c356b68 100644 --- a/config.h.in +++ b/config.h.in @@ -6,6 +6,9 @@ /* Define to use fixed-point computation */ #cmakedefine FIXED_POINT +/* Define to use thread-local storage for random number generator */ +#cmakedefine PS_USE_THREAD_LOCAL_RNG + /* Define if the system has the type `long long'. */ #cmakedefine HAVE_LONG_LONG diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index af108b7d..1c8a24fd 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,4 +1,8 @@ configure_file(test_macros.h.in test_macros.h @ONLY) + +# Build thread utilities as a library +add_library(test_thread_utils STATIC test_thread_utils.c) +target_include_directories(test_thread_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set(TESTS test_acmod test_acmod_grow @@ -33,6 +37,12 @@ set(TESTS test_vad test_word_align test_endpointer + test_thread_local_compile + test_thread_local_basic + test_thread_utils_self + test_genrand_baseline + test_genrand_thread + test_genrand_thread_tls ) foreach(TEST_EXECUTABLE ${TESTS}) add_executable(${TEST_EXECUTABLE} EXCLUDE_FROM_ALL ${TEST_EXECUTABLE}.c) @@ -46,6 +56,20 @@ foreach(TEST_EXECUTABLE ${TESTS}) add_dependencies(check ${TEST_EXECUTABLE}) endforeach() +# Some tests need thread utilities and pthread support +if(NOT WIN32) + find_package(Threads REQUIRED) + target_link_libraries(test_thread_local_basic ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(test_thread_utils ${CMAKE_THREAD_LIBS_INIT}) +endif() + +# test_thread_utils_self needs the thread utilities library +target_link_libraries(test_thread_utils_self test_thread_utils) + +# test_genrand_thread needs thread utilities +target_link_libraries(test_genrand_thread test_thread_utils) +target_link_libraries(test_genrand_thread_tls test_thread_utils) + add_subdirectory(test_alloc) add_subdirectory(test_case) add_subdirectory(test_feat)