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:
parent
57cfd221a6
commit
c5989473b9
@ -12,6 +12,7 @@
|
||||
gcc:
|
||||
extends: .test
|
||||
variables:
|
||||
CONFIG: "--without-tls"
|
||||
CFLAGS: "-O2 -std=c89 -D_XOPEN_SOURCE=600"
|
||||
|
||||
gcc:minimum:
|
||||
|
@ -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
|
||||
|
26
configure.ac
26
configure.ac
@ -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
29
dict.c
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user