/*************************************************************************/
-int nlopt_srand_called = 0;
+static THREADLOCAL int nlopt_srand_called = 0;
void nlopt_srand(unsigned long seed) {
nlopt_srand_called = 1;
nlopt_init_genrand(seed);
nlopt_srand(nlopt_time_seed());
}
+void nlopt_srand_time_default() {
+ if (!nlopt_srand_called) nlopt_srand_time();
+}
+
/*************************************************************************/
};
/*********************************************************************/
-extern int nlopt_srand_called; /* whether the random seed is initialized */
+void nlopt_srand_time_default(void); /* init the rand. seed only if unset */
/*********************************************************************/
/* global defaults set by deprecated API: */
*minf = HUGE_VAL;
/* make sure rand generator is inited */
- if (!nlopt_srand_called)
- nlopt_srand_time(); /* default is non-deterministic */
+ nlopt_srand_time_default(); /* default is non-deterministic */
/* check bound constraints */
for (i = 0; i < n; ++i)
AC_CHECK_HEADERS([unistd.h getopt.h stdint.h])
AC_C_CONST
AC_C_INLINE
+AX_C_THREADLOCAL
dnl find 32-bit unsigned integer type for random-number generator
AC_CHECK_SIZEOF(unsigned int)
--- /dev/null
+dnl @synopsis AX_C_THREADLOCAL([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl @summary determine C keyword for threadlocal storage
+dnl
+dnl This macro tries to discover a C keyword to declare variables
+dnl as having thread-local storage. Most commonly, this is either
+dnl __thread [gcc] or __declspec(thread) [Windows].
+dnl
+dnl On success, it #defines the THREADLOCAL preprocessor symbol to
+dnl the appropriate keyword. You would then use it in C code as, e.g.:
+dnl THREADLOCAL int myvariable;
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if an thread-local
+dnl keyword is found, and ACTION-IF-NOT-FOUND is a list of commands
+dnl to run it if one is not found. If ACTION-IF-FOUND is not specified,
+dnl the default action does nothing.
+dnl
+dnl @version 2010-05-28
+dnl @license GPLWithACException
+dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
+AC_DEFUN([AX_C_THREADLOCAL],
+[AC_CACHE_CHECK([for C thread-local keyword], acx_cv_c_threadlocal,
+[acx_cv_c_threadlocal=unsupported
+ AC_LANG_SAVE
+ AC_LANG_C
+ for acx_kw in __thread "__declspec(thread)"; do
+ AC_TRY_COMPILE([], [static $acx_kw int x = 0;],
+ [acx_cv_c_threadlocal=$acx_kw; break])
+ done
+ AC_LANG_RESTORE
+])
+ acx_kw="$acx_cv_c_threadlocal"
+ if test "$acx_kw" = unsupported; then acx_kw=""; fi
+ AC_DEFINE_UNQUOTED(THREADLOCAL, $acx_kw, [Define to C thread-local keyword, or to nothing if this is not supported in your compiler.])
+ if test "$acx_cv_c_threadlocal" = unsupported; then
+ m4_default([$2],:)
+ else
+ m4_default([$1],:)
+ fi
+])
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
-static uint32_t mt[N]; /* the array for the state vector */
-static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
+/* SGJ 2010: make RNG thread-safe by declaring the RNG state as thread-local
+ storage, at least for GCC, MSVC, and Intel C++ */
+
+static THREADLOCAL uint32_t mt[N]; /* the array for the state vector */
+static THREADLOCAL int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
/* initializes mt[N] with a seed */
void nlopt_init_genrand(unsigned long s)