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);
|
void srand(unsigned int seed);
|
||||||
int rand(void);
|
int rand(void);
|
||||||
|
int rand_r(FAR unsigned int *seedp);
|
||||||
void lcong48(FAR unsigned short int param[7]);
|
void lcong48(FAR unsigned short int param[7]);
|
||||||
FAR unsigned short int *seed48(FAR unsigned short int seed16v[3]);
|
FAR unsigned short int *seed48(FAR unsigned short int seed16v[3]);
|
||||||
void srand48(long int seedval);
|
void srand48(long int seedval);
|
||||||
|
@ -67,9 +67,9 @@ typedef double float_t;
|
|||||||
|
|
||||||
/* First order congruential generators */
|
/* 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)
|
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
||||||
static float_t frand1(void);
|
static float_t frand1(FAR unsigned long *seed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Second order congruential generators */
|
/* Second order congruential generators */
|
||||||
@ -106,7 +106,7 @@ static unsigned long g_randint3;
|
|||||||
|
|
||||||
/* First order congruential generators */
|
/* First order congruential generators */
|
||||||
|
|
||||||
static inline unsigned long fgenerate1(void)
|
static inline unsigned long fgenerate1(FAR unsigned long *seed)
|
||||||
{
|
{
|
||||||
unsigned long randint;
|
unsigned long randint;
|
||||||
|
|
||||||
@ -115,17 +115,17 @@ static inline unsigned long fgenerate1(void)
|
|||||||
* the first order random number generator.
|
* the first order random number generator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
randint = (RND1_CONSTK * g_randint1) % RND1_CONSTP;
|
randint = (RND1_CONSTK * (*seed)) % RND1_CONSTP;
|
||||||
g_randint1 = (randint == 0 ? 1 : randint);
|
*seed = (randint == 0 ? 1 : randint);
|
||||||
return randint;
|
return randint;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
||||||
static float_t frand1(void)
|
static float_t frand1(FAR unsigned long *seed)
|
||||||
{
|
{
|
||||||
/* First order congruential generator. */
|
/* 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 */
|
/* 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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
static unsigned long nrand_r(unsigned long limit,
|
||||||
* Public Functions
|
FAR unsigned long *seed)
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
float_t ratio;
|
float_t ratio;
|
||||||
@ -260,7 +228,7 @@ unsigned long nrand(unsigned long limit)
|
|||||||
/* Get a random integer in the range 0.0 - 1.0 */
|
/* Get a random integer in the range 0.0 - 1.0 */
|
||||||
|
|
||||||
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
#if (CONFIG_LIBC_RAND_ORDER == 1)
|
||||||
ratio = frand1();
|
ratio = frand1(seed);
|
||||||
#elif (CONFIG_LIBC_RAND_ORDER == 2)
|
#elif (CONFIG_LIBC_RAND_ORDER == 2)
|
||||||
ratio = frand2();
|
ratio = frand2();
|
||||||
#else /* if (CONFIG_LIBC_RAND_ORDER > 2) */
|
#else /* if (CONFIG_LIBC_RAND_ORDER > 2) */
|
||||||
@ -279,3 +247,65 @@ unsigned long nrand(unsigned long limit)
|
|||||||
|
|
||||||
return result;
|
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