Add a function returning a 32 bit random value. Callers that only need 32 bits currently have to truncate the result of rte_rand(), which assumes that the low bits of the generator are as good as the high ones. That happens to hold for the current generator but is not a property callers should have to know about.
Returning the high bits keeps the function correct for the common case where a generator has weaker low order bits. Signed-off-by: Stephen Hemminger <[email protected]> --- doc/guides/rel_notes/release_26_11.rst | 2 ++ lib/eal/common/rte_random.c | 10 +++++++ lib/eal/include/rte_random.h | 39 +++++++++++++++++++------- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index 5852f7acfb..1dc634d504 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -58,6 +58,8 @@ New Features * **Updated random number generation.** * The initial seed is now always taken from ``getentropy()``. + * Added ``rte_rand32()`` for callers which only need 32 bits and would + otherwise have to truncate the result of ``rte_rand()``. Removed Items diff --git a/lib/eal/common/rte_random.c b/lib/eal/common/rte_random.c index b036c50349..1368b70e27 100644 --- a/lib/eal/common/rte_random.c +++ b/lib/eal/common/rte_random.c @@ -158,6 +158,16 @@ rte_rand(void) return __rte_rand_lfsr258(state); } +RTE_EXPORT_SYMBOL(rte_rand32) +uint32_t +rte_rand32(void) +{ + /* Use the high bits, they are the ones that stay good if the + * underlying generator is ever changed. + */ + return (uint32_t)(rte_rand() >> 32); +} + RTE_EXPORT_SYMBOL(rte_rand_max) uint64_t rte_rand_max(uint64_t upper_bound) diff --git a/lib/eal/include/rte_random.h b/lib/eal/include/rte_random.h index 978ecda203..9d3ecc596e 100644 --- a/lib/eal/include/rte_random.h +++ b/lib/eal/include/rte_random.h @@ -13,6 +13,8 @@ #include <stdint.h> +#include <rte_compat.h> + #ifdef __cplusplus extern "C" { #endif @@ -27,7 +29,7 @@ extern "C" { * * This function is not multi-thread safe in regards to other * rte_srand() calls, nor is it in relation to concurrent rte_rand(), - * rte_rand_max() or rte_drand() calls. + * rte_rand32(), rte_rand_max() or rte_drand() calls. * * @param seedval * The value of the seed. @@ -40,9 +42,9 @@ rte_srand(uint64_t seedval); * * The generator is not cryptographically secure. * - * rte_rand(), rte_rand_max() and rte_drand() are multi-thread safe, - * with the exception that they may not be called by multiple - * _unregistered_ non-EAL threads in parallel. + * rte_rand(), rte_rand32(), rte_rand_max() and rte_drand() are + * multi-thread safe, with the exception that they may not be called + * by multiple _unregistered_ non-EAL threads in parallel. * * @return * A pseudo-random value between 0 and (1<<64)-1. @@ -50,15 +52,32 @@ rte_srand(uint64_t seedval); uint64_t rte_rand(void); +/** + * Get a 32 bit pseudo-random value. + * + * Prefer this over truncating the result of rte_rand() since not + * every generator produces equally good values in all bit positions. + * + * The generator is not cryptographically secure. + * + * This function is multi-thread safe, with the exception that it may + * not be called by multiple _unregistered_ non-EAL threads in parallel. + * + * @return + * A pseudo-random value between 0 and (1<<32)-1. + */ +uint32_t +rte_rand32(void); + /** * Generates a pseudo-random number with an upper bound. * * This function returns an uniformly distributed (unbiased) random * number less than a user-specified maximum value. * - * rte_rand(), rte_rand_max() and rte_drand() are multi-thread safe, - * with the exception that they may not be called by multiple - * _unregistered_ non-EAL threads in parallel. + * rte_rand(), rte_rand32(), rte_rand_max() and rte_drand() are + * multi-thread safe, with the exception that they may not be called + * by multiple _unregistered_ non-EAL threads in parallel. * * @param upper_bound * The upper bound of the generated number. @@ -76,9 +95,9 @@ rte_rand_max(uint64_t upper_bound); * * The generator is not cryptographically secure. * - * rte_rand(), rte_rand_max() and rte_drand() are multi-thread safe, - * with the exception that they may not be called by multiple - * _unregistered_ non-EAL threads in parallel. + * rte_rand(), rte_rand32(), rte_rand_max() and rte_drand() are + * multi-thread safe, with the exception that they may not be called + * by multiple _unregistered_ non-EAL threads in parallel. * * @return * A pseudo-random value between 0 and 1.0. -- 2.53.0

