From f57cb6099e5f9f4dfc5208c36b9130c9837410e6 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 18 Mar 2022 21:32:53 +0000 Subject: [PATCH] [Minor] Use wyrand for fast random as we already use mumhash for fast hashing --- src/libutil/util.c | 92 ++++++++++++++++++++++------------------------ src/libutil/util.h | 2 +- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/libutil/util.c b/src/libutil/util.c index 44f40280b..ec86d22ea 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -1757,80 +1757,76 @@ rspamd_random_double (void) static guint64* -xorshifto_seed (void) +rspamd_fast_random_seed (void) { - static guint64 xorshifto_seed[4]; - static bool initialized = false; + static guint64 seed; - if (G_UNLIKELY(!initialized)) { - ottery_rand_bytes((void *)xorshifto_seed, sizeof (xorshifto_seed)); - initialized = true; + if (G_UNLIKELY(seed == 0)) { + ottery_rand_bytes((void *)&seed, sizeof (seed)); } - return xorshifto_seed; + return &seed; } -static inline guint64 -xoroshiro_rotl (const guint64 x, int k) { - return (x << k) | (x >> (64 - k)); +/* wyrand */ +static inline uint64_t +rspamd_random_uint64_fast_seed (uint64_t *seed) +{ + *seed += UINT64_C(0xa0761d6478bd642f); +#ifdef __SIZEOF_INT128__ +# if defined(__aarch64__) + uint64_t lo, hi, p = *seed ^ UINT64_C(0xe7037ed1a0b428db), v = *seed; + lo = v * p; + __asm__ ("umulh %0, %1, %2" : "=r" (hi) : "r" (v), "r" (p)); + return lo ^ hi; +# else + __uint128_t t = (__uint128_t)*seed * (*seed ^ UINT64_C(0xe7037ed1a0b428db)); + return (t >> 64) ^ t; +# endif +#else + /* Implementation of 64x64->128-bit multiplication by four 32x32->64 + * bit multiplication. */ + uint64_t lo, hi, p = *seed ^ UINT64_C(0xe7037ed1a0b428db), v = *seed; + uint64_t hv = v >> 32, hp = p >> 32; + uint64_t lv = (uint32_t) v, lp = (uint32_t) p; + uint64_t rh = hv * hp; + uint64_t rm_0 = hv * lp; + uint64_t rm_1 = hp * lv; + uint64_t rl = lv * lp; + uint64_t t; + + /* We could ignore a carry bit here if we did not care about the + same hash for 32-bit and 64-bit targets. */ + t = rl + (rm_0 << 32); + lo = t + (rm_1 << 32); + hi = rh + (rm_0 >> 32) + (rm_1 >> 32); + return lo ^ hi; +#endif } gdouble rspamd_random_double_fast (void) { - return rspamd_random_double_fast_seed (xorshifto_seed()); + return rspamd_random_double_fast_seed (rspamd_fast_random_seed()); } /* xoshiro256+ */ inline gdouble -rspamd_random_double_fast_seed (guint64 seed[4]) -{ - const uint64_t result = seed[0] + seed[3]; - - const uint64_t t = seed[1] << 17; - - seed[2] ^= seed[0]; - seed[3] ^= seed[1]; - seed[1] ^= seed[2]; - seed[0] ^= seed[3]; - - seed[2] ^= t; - - seed[3] = xoroshiro_rotl (seed[3], 45); - - return rspamd_double_from_int64 (result); -} - -/* xoroshiro256** */ -static inline guint64 -rspamd_random_uint64_fast_seed (guint64 seed[4]) +rspamd_random_double_fast_seed (guint64 *seed) { - const uint64_t result = xoroshiro_rotl (seed[1] * 5, 7) * 9; - - const uint64_t t = seed[1] << 17; - - seed[2] ^= seed[0]; - seed[3] ^= seed[1]; - seed[1] ^= seed[2]; - seed[0] ^= seed[3]; - - seed[2] ^= t; - - seed[3] = xoroshiro_rotl (seed[3], 45); - - return result; + return rspamd_double_from_int64 (rspamd_random_uint64_fast_seed(seed)); } guint64 rspamd_random_uint64_fast (void) { - return rspamd_random_uint64_fast_seed (xorshifto_seed()); + return rspamd_random_uint64_fast_seed (rspamd_fast_random_seed()); } void rspamd_random_seed_fast (void) { - (void)xorshifto_seed(); + (void)rspamd_fast_random_seed(); } gdouble diff --git a/src/libutil/util.h b/src/libutil/util.h index 1d53807d4..f9be15d28 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -372,7 +372,7 @@ gdouble rspamd_random_double (void); * @return */ gdouble rspamd_random_double_fast (void); -gdouble rspamd_random_double_fast_seed (guint64 seed[4]); +gdouble rspamd_random_double_fast_seed (guint64 *seed); guint64 rspamd_random_uint64_fast (void); /** -- 2.39.5