1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-03-25 10:50:08 +03:00

dict: Use thread-local storage for PRNG state

This commit is contained in:
Nick Wellnhofer 2023-09-01 14:52:11 +02:00
parent 57cfd221a6
commit c5989473b9
4 changed files with 69 additions and 11 deletions

View File

@ -12,6 +12,7 @@
gcc:
extends: .test
variables:
CONFIG: "--without-tls"
CFLAGS: "-O2 -std=c89 -D_XOPEN_SOURCE=600"
gcc:minimum:

View File

@ -206,6 +206,30 @@ if (NOT MSVC)
endif()
endif()
check_c_source_compiles(
"_Thread_local int v; int main(){return 0;}"
XML_THREAD_LOCAL_C11
)
if (XML_THREAD_LOCAL_C11)
set(XML_THREAD_LOCAL "_Thread_local")
else()
check_c_source_compiles(
"__thread int v; int main(){return 0;}"
XML_THREAD_LOCAL_THREAD
)
if (XML_THREAD_LOCAL_THREAD)
set(XML_THREAD_LOCAL "__thread")
else()
check_c_source_compiles(
"__declspec(thread) int v; int main(){return 0;}"
XML_THREAD_LOCAL_DECLSPEC
)
if (XML_THREAD_LOCAL_DECLSPEC)
set(XML_THREAD_LOCAL "__declspec(thread)")
endif()
endif()
endif()
set(
LIBXML2_HDRS
include/libxml/c14n.h

View File

@ -135,6 +135,8 @@ AC_ARG_WITH(minimum,
AC_ARG_WITH(legacy,
[ --with-legacy maximum ABI compatibility (off)])
AC_ARG_WITH(tls,
[ --with-tls thread-local storage (on)])
AC_ARG_WITH(fexceptions,
[ --with-fexceptions add GCC flag -fexceptions for C++ exceptions (off)])
AC_ARG_WITH(coverage,
@ -435,6 +437,20 @@ XML_LIBDIR='-L${libdir}'
XML_INCLUDEDIR='-I${includedir}/libxml2'
XML_CFLAGS=""
dnl Thread-local storage
if test "$with_tls" != "no"; then
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([_Thread_local int v;]) ], [
AC_DEFINE([XML_THREAD_LOCAL], [_Thread_local], [TLS specifier]) ], [
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([__thread int v;]) ], [
AC_DEFINE([XML_THREAD_LOCAL], [__thread], [TLS specifier]) ], [
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([__declspec(thread) int v;]) ], [
AC_DEFINE([XML_THREAD_LOCAL], [__declspec(thread)], [TLS specifier]) ], [
WARN_NO_TLS=1 ])])])
fi
dnl Checking whether __attribute__((destructor)) is accepted by the compiler
AC_MSG_CHECKING([whether __attribute__((destructor)) is accepted])
AC_TRY_COMPILE2([
@ -1156,10 +1172,10 @@ AC_CONFIG_FILES([python/setup.py], [chmod +x python/setup.py])
AC_CONFIG_FILES([xml2-config], [chmod +x xml2-config])
AC_OUTPUT
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_Thread_local int v;])], [], [
if test "$WARN_NO_TLS" != ""; then
echo "================================================================"
echo "WARNING: Your C compiler doesn't support C11."
echo "Future versions of libxml2 will probably require a C11 compiler,"
echo "at least for features like multi-threading."
echo "WARNING: Your C compiler appears to not support thread-local"
echo "storage. Future versions of libxml2 will require this feature"
echo "for multi-threading."
echo "================================================================"
])
fi

29
dict.c
View File

@ -132,7 +132,12 @@ static xmlMutex xmlDictMutex;
/*
* Internal data for random function, protected by xmlDictMutex
*/
static uint32_t rand_seed[2];
static uint32_t globalRngState[2];
#ifdef XML_THREAD_LOCAL
XML_THREAD_LOCAL static int localRngInitialized = 0;
XML_THREAD_LOCAL static uint32_t localRngState[2];
#endif
/**
* xmlInitializeDict:
@ -162,10 +167,10 @@ xmlInitDictInternal(void) {
/* TODO: Get seed values from system PRNG */
rand_seed[0] = (uint32_t) time(NULL) ^
HASH_ROL((uint32_t) (size_t) &xmlInitializeDict, 8);
rand_seed[1] = HASH_ROL((uint32_t) (size_t) &xmlDictMutex, 16) ^
HASH_ROL((uint32_t) (size_t) &var, 24);
globalRngState[0] = (uint32_t) time(NULL) ^
HASH_ROL((uint32_t) (size_t) &xmlInitializeDict, 8);
globalRngState[1] = HASH_ROL((uint32_t) (size_t) &xmlDictMutex, 16) ^
HASH_ROL((uint32_t) (size_t) &var, 24);
}
#ifdef __clang__
@ -187,13 +192,25 @@ xoroshiro64ss(uint32_t *s) {
unsigned
xmlRandom(void) {
#ifdef XML_THREAD_LOCAL
if (!localRngInitialized) {
xmlMutexLock(&xmlDictMutex);
localRngState[0] = xoroshiro64ss(globalRngState);
localRngState[1] = xoroshiro64ss(globalRngState);
localRngInitialized = 1;
xmlMutexUnlock(&xmlDictMutex);
}
return(xoroshiro64ss(localRngState));
#else
uint32_t ret;
xmlMutexLock(&xmlDictMutex);
ret = xoroshiro64ss(rand_seed);
ret = xoroshiro64ss(globalRngState);
xmlMutexUnlock(&xmlDictMutex);
return(ret);
#endif
}
/**