[svn-r12019] Purpose:

Bug fix/Feature

Description:
Modify the library to use rand_r, when available, instead of srand.  If
rand_r is not available, it will try to use srandom/random, and then finally
fall back to srand/rand.

Solution:
A couple places in the library use the srand() function to seed the random
number generator.  This can cause problems on certain platforms and could theoretically
cause problems for users who expect a certain sequence of random numbers following their
own call to srand().

Most platforms have an implementation of rand_r, which is identical to rand, except that
it allows for explicit storage of the seed value.  The configure script will now check
for the existence of rand_r to facilitate its use in the library.

Two new functions are added, to replace the macros HDsrand/HDrand.  These functions are HDrand and
HDsrand.  HDrand will call rand_r, if available, or random(), if available, and fall back to rand() if neither
of those is available.  HDsrand will store the seed value locally, if rand_r is available.  Otherwise, it will call
srandom if available, and fall back to srand otherwise.


Platforms tested:
heping, mir.  Really need to test on Red Storm, since that platform motivated this fix, but the machine
is currently not available.

Misc. update:
This commit is contained in:
Leon Arber 2006-03-06 23:23:24 -05:00
parent 4efe32d542
commit 840bcbe9ef
7 changed files with 61 additions and 20 deletions

3
configure vendored
View File

@ -46663,7 +46663,8 @@ done
for ac_func in random srandom
for ac_func in rand_r random srandom
do do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5 echo "$as_me:$LINENO: checking for $ac_func" >&5

View File

@ -1606,7 +1606,7 @@ dnl
AC_CHECK_FUNCS(alarm fork frexpf frexpl gethostname getpwuid getrusage) AC_CHECK_FUNCS(alarm fork frexpf frexpl gethostname getpwuid getrusage)
AC_CHECK_FUNCS(BSDgettimeofday longjmp setsysinfo sigaction) AC_CHECK_FUNCS(BSDgettimeofday longjmp setsysinfo sigaction)
AC_CHECK_FUNCS(signal snprintf vasprintf strdup system waitpid) AC_CHECK_FUNCS(signal snprintf vasprintf strdup system waitpid)
AC_CHECK_FUNCS(random srandom) AC_CHECK_FUNCS(rand_r random srandom)
AC_CHECK_FUNCS(tmpfile) AC_CHECK_FUNCS(tmpfile)
dnl Check for vsnprintf() separately, so we can detect situations where it dnl Check for vsnprintf() separately, so we can detect situations where it

View File

@ -3114,3 +3114,48 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
HDfflush (out); HDfflush (out);
return event_time.etime; return event_time.etime;
} }
/*-------------------------------------------------------------------------
* Function: HDrand/HDsrand
*
* Purpose: Wrapper function for rand. If rand_r exists on this system,
* use it. Otherwise, just call random() or rand().
*
* Wrapper function for srand. If rand_r is available, it will keep
* track of the seed locally instead of using srand() which modifies
* global state and can break other programs. Otherwise, just call
* srandom() or srand().
*
* Return: Success: Random number from 0 to RAND_MAX
*
* Failure: Cannot fail.
*
* Programmer: Leon Arber
* March 6, 2006.
*
* Modifications:
*-------------------------------------------------------------------------
*/
static unsigned int g_seed = 42;
int HDrand(void)
{
#ifdef H5_HAVE_RAND_R
return rand_r(&g_seed);
#elif H5_HAVE_RANDOM
return random();
#else
return rand();
#endif
}
void HDsrand(unsigned int seed)
{
#ifdef H5_HAVE_RAND_R
g_seed = seed;
#elif H5_HAVE_RANDOM
return srandom(seed);
#else
return srand(seed);
#endif
}

View File

@ -203,7 +203,7 @@ H5FL_BARR_DEFINE_STATIC(H5SL_node_t,H5SL_node_ptr_t,H5SL_LEVEL_MAX);
EXAMPLES EXAMPLES
REVISION LOG REVISION LOG
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
static herr_t static herr_t
H5SL_init_interface(void) H5SL_init_interface(void)
{ {
time_t curr_time; /* Current time, for seeding random number generator */ time_t curr_time; /* Current time, for seeding random number generator */
@ -214,12 +214,14 @@ H5SL_init_interface(void)
* This causes Lustre on Redstorm to hang with following errors. (Lustre * This causes Lustre on Redstorm to hang with following errors. (Lustre
* has fix it, but not deployed at RedStorm yet. * has fix it, but not deployed at RedStorm yet.
* (client.c:568:ptlrpc_check_status()) @@@ type == PTL_RPC_MSG_ERR, err == -114 req@0x57a9660 x1/t0 o38->mds_l2@MDS_PEER_UUID:12 lens 240/272 ref 1 fl Rpc:R/100000/0 rc 0/-114 * (client.c:568:ptlrpc_check_status()) @@@ type == PTL_RPC_MSG_ERR, err == -114 req@0x57a9660 x1/t0 o38->mds_l2@MDS_PEER_UUID:12 lens 240/272 ref 1 fl Rpc:R/100000/0 rc 0/-114
*/ *
#ifndef RED_STORM * 3/6/06. LA:
/* Create randomized set of numbers */ * Shouldn't need patch anymore because HDsrand will use rand_r on Red Storm instead of srand.
*/
/* Create randomized set of numbers */
curr_time=HDtime(NULL); curr_time=HDtime(NULL);
HDsrand((unsigned)curr_time); HDsrand((unsigned)curr_time);
#endif
FUNC_LEAVE_NOAPI(SUCCEED) FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SL_init_interface() */ } /* end H5SL_init_interface() */

View File

@ -208,6 +208,9 @@
/* Define to 1 if you have the `random' function. */ /* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM #undef HAVE_RANDOM
/* Define to 1 if you have the `rand_r' function. */
#undef HAVE_RAND_R
/* Define to 1 if you have the <setjmp.h> header file. */ /* Define to 1 if you have the <setjmp.h> header file. */
#undef HAVE_SETJMP_H #undef HAVE_SETJMP_H

View File

@ -772,12 +772,8 @@ typedef off_t h5_stat_size_t;
#define HDputs(S) puts(S) #define HDputs(S) puts(S)
#define HDqsort(M,N,Z,F) qsort(M,N,Z,F) #define HDqsort(M,N,Z,F) qsort(M,N,Z,F)
#define HDraise(N) raise(N) #define HDraise(N) raise(N)
#define HDrand() rand() #define HDrandom() HDrand()
#ifdef H5_HAVE_RANDOM #define HDsrandom(S) HDsrand(S)
#define HDrandom() random()
#else
#define HDrandom() rand()
#endif
#define HDread(F,M,Z) read(F,M,Z) #define HDread(F,M,Z) read(F,M,Z)
#define HDreaddir(D) readdir(D) #define HDreaddir(D) readdir(D)
#define HDrealloc(M,Z) realloc(M,Z) #define HDrealloc(M,Z) realloc(M,Z)
@ -817,12 +813,6 @@ typedef off_t h5_stat_size_t;
#endif #endif
/* sprintf() variable arguments */ /* sprintf() variable arguments */
#define HDsqrt(X) sqrt(X) #define HDsqrt(X) sqrt(X)
#define HDsrand(N) srand(N)
#ifdef H5_HAVE_SRANDOM
#define HDsrandom(N) srandom(N)
#else
#define HDsrandom(N) srand(N)
#endif
/* sscanf() variable arguments */ /* sscanf() variable arguments */

View File

@ -3811,7 +3811,7 @@ test_select_hyper_union_random_5d(hid_t read_plist)
#else /* QAK */ #else /* QAK */
seed=987909620; seed=987909620;
#endif /* QAK */ #endif /* QAK */
srand(seed); HDsrand(seed);
#ifdef QAK #ifdef QAK
printf("test_num=%d, seed=%u\n",test_num,seed); printf("test_num=%d, seed=%u\n",test_num,seed);