libc/rand_r: support rand_r api
refs to https://pubs.opengroup.org/onlinepubs/7908799/xsh/rand.html Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
97a2528de9
commit
5d09b4cbd0
@ -132,6 +132,7 @@ extern "C"
|
||||
|
||||
void srand(unsigned int seed);
|
||||
int rand(void);
|
||||
int rand_r(FAR unsigned int *seedp);
|
||||
void lcong48(FAR unsigned short int param[7]);
|
||||
FAR unsigned short int *seed48(FAR unsigned short int seed16v[3]);
|
||||
void srand48(long int seedval);
|
||||
|
@ -67,9 +67,9 @@ typedef double float_t;
|
||||
|
||||
/* First order congruential generators */
|
||||
|
||||
static inline unsigned long fgenerate1(void);
|
||||
static inline unsigned long fgenerate1(FAR unsigned long *seed);
|
||||
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
||||
static float_t frand1(void);
|
||||
static float_t frand1(FAR unsigned long *seed);
|
||||
#endif
|
||||
|
||||
/* Second order congruential generators */
|
||||
@ -106,7 +106,7 @@ static unsigned long g_randint3;
|
||||
|
||||
/* First order congruential generators */
|
||||
|
||||
static inline unsigned long fgenerate1(void)
|
||||
static inline unsigned long fgenerate1(FAR unsigned long *seed)
|
||||
{
|
||||
unsigned long randint;
|
||||
|
||||
@ -115,17 +115,17 @@ static inline unsigned long fgenerate1(void)
|
||||
* the first order random number generator.
|
||||
*/
|
||||
|
||||
randint = (RND1_CONSTK * g_randint1) % RND1_CONSTP;
|
||||
g_randint1 = (randint == 0 ? 1 : randint);
|
||||
randint = (RND1_CONSTK * (*seed)) % RND1_CONSTP;
|
||||
*seed = (randint == 0 ? 1 : randint);
|
||||
return randint;
|
||||
}
|
||||
|
||||
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
||||
static float_t frand1(void)
|
||||
static float_t frand1(FAR unsigned long *seed)
|
||||
{
|
||||
/* First order congruential generator. */
|
||||
|
||||
unsigned long randint = fgenerate1();
|
||||
unsigned long randint = fgenerate1(seed);
|
||||
|
||||
/* Construct an floating point value in the range from 0.0 up to 1.0 */
|
||||
|
||||
@ -215,40 +215,8 @@ static float_t frand3(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: srand
|
||||
*
|
||||
* Description:
|
||||
* Seed the congruential random number generator.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void srand(unsigned int seed)
|
||||
{
|
||||
g_randint1 = seed;
|
||||
#if (CONFIG_LIBC_RAND_ORDER > 1)
|
||||
g_randint2 = seed;
|
||||
fgenerate1();
|
||||
#if (CONFIG_LIBC_RAND_ORDER > 2)
|
||||
g_randint3 = seed;
|
||||
fgenerate2();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrand
|
||||
*
|
||||
* Description:
|
||||
* Return a random, unsigned long value in the range of 0 to (limit - 1)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned long nrand(unsigned long limit)
|
||||
static unsigned long nrand_r(unsigned long limit,
|
||||
FAR unsigned long *seed)
|
||||
{
|
||||
unsigned long result;
|
||||
float_t ratio;
|
||||
@ -260,7 +228,7 @@ unsigned long nrand(unsigned long limit)
|
||||
/* Get a random integer in the range 0.0 - 1.0 */
|
||||
|
||||
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
||||
ratio = frand1();
|
||||
ratio = frand1(seed);
|
||||
#elif (CONFIG_LIBC_RAND_ORDER == 2)
|
||||
ratio = frand2();
|
||||
#else /* if (CONFIG_LIBC_RAND_ORDER > 2) */
|
||||
@ -279,3 +247,65 @@ unsigned long nrand(unsigned long limit)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: srand
|
||||
*
|
||||
* Description:
|
||||
* Seed the congruential random number generator.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void srand(unsigned int seed)
|
||||
{
|
||||
g_randint1 = seed;
|
||||
#if (CONFIG_LIBC_RAND_ORDER > 1)
|
||||
g_randint2 = seed;
|
||||
fgenerate1(&g_randint1);
|
||||
#if (CONFIG_LIBC_RAND_ORDER > 2)
|
||||
g_randint3 = seed;
|
||||
fgenerate2();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nrand
|
||||
*
|
||||
* Description:
|
||||
* Return a random, unsigned long value in the range of 0 to (limit - 1)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned long nrand(unsigned long limit)
|
||||
{
|
||||
return nrand_r(limit, &g_randint1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rand_r
|
||||
*
|
||||
* Description:
|
||||
* The function rand() is not reentrant, since it uses hidden state that
|
||||
* is modified on each call. This might just be the seed value to be used
|
||||
* by the next call, or it might be something more elaborate. In order to
|
||||
* get reproducible behavior in a threaded application, this state must be
|
||||
* made explicit; this can be done using the reentrant function rand_r().
|
||||
*
|
||||
* Return a random, int value in the range of 0 to INT_MAX.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rand_r(FAR unsigned int *seedp)
|
||||
{
|
||||
unsigned long seed = *seedp;
|
||||
unsigned long rand;
|
||||
|
||||
rand = nrand_r(INT_MAX, &seed);
|
||||
*seedp = (unsigned int)seed;
|
||||
return (int)rand;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user