1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Ericsson AB
7 #include <rte_branch_prediction.h>
8 #include <rte_cycles.h>
10 #include <rte_lcore.h>
11 #include <rte_memory.h>
12 #include <rte_random.h>
14 struct rte_rand_state {
20 } __rte_cache_aligned;
22 static struct rte_rand_state rand_states[RTE_MAX_LCORE];
25 __rte_rand_lcg32(uint32_t *seed)
27 *seed = 1103515245U * *seed + 12345U;
33 __rte_rand_lcg64(uint32_t *seed)
38 /* A 64-bit LCG would have been much cleaner, but good
39 * multiplier/increments for such seem hard to come by.
42 low = __rte_rand_lcg32(seed);
43 high = __rte_rand_lcg32(seed);
45 return low | (high << 32);
49 __rte_rand_lfsr258_gen_seed(uint32_t *seed, uint64_t min_value)
53 res = __rte_rand_lcg64(seed);
62 __rte_srand_lfsr258(uint64_t seed, struct rte_rand_state *state)
66 lcg_seed = (uint32_t)(seed ^ (seed >> 32));
68 state->z1 = __rte_rand_lfsr258_gen_seed(&lcg_seed, 2UL);
69 state->z2 = __rte_rand_lfsr258_gen_seed(&lcg_seed, 512UL);
70 state->z3 = __rte_rand_lfsr258_gen_seed(&lcg_seed, 4096UL);
71 state->z4 = __rte_rand_lfsr258_gen_seed(&lcg_seed, 131072UL);
72 state->z5 = __rte_rand_lfsr258_gen_seed(&lcg_seed, 8388608UL);
76 rte_srand(uint64_t seed)
78 unsigned int lcore_id;
80 /* add lcore_id to seed to avoid having the same sequence */
81 for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
82 __rte_srand_lfsr258(seed + lcore_id, &rand_states[lcore_id]);
85 static __rte_always_inline uint64_t
86 __rte_rand_lfsr258_comp(uint64_t z, uint64_t a, uint64_t b, uint64_t c,
89 return ((z & c) << d) ^ (((z << a) ^ z) >> b);
92 /* Based on L’Ecuyer, P.: Tables of maximally equidistributed combined
96 static __rte_always_inline uint64_t
97 __rte_rand_lfsr258(struct rte_rand_state *state)
99 state->z1 = __rte_rand_lfsr258_comp(state->z1, 1UL, 53UL,
100 18446744073709551614UL, 10UL);
101 state->z2 = __rte_rand_lfsr258_comp(state->z2, 24UL, 50UL,
102 18446744073709551104UL, 5UL);
103 state->z3 = __rte_rand_lfsr258_comp(state->z3, 3UL, 23UL,
104 18446744073709547520UL, 29UL);
105 state->z4 = __rte_rand_lfsr258_comp(state->z4, 5UL, 24UL,
106 18446744073709420544UL, 23UL);
107 state->z5 = __rte_rand_lfsr258_comp(state->z5, 3UL, 33UL,
108 18446744073701163008UL, 8UL);
110 return state->z1 ^ state->z2 ^ state->z3 ^ state->z4 ^ state->z5;
113 static __rte_always_inline
114 struct rte_rand_state *__rte_rand_get_state(void)
116 unsigned int lcore_id;
118 lcore_id = rte_lcore_id();
120 if (unlikely(lcore_id == LCORE_ID_ANY))
121 lcore_id = rte_get_master_lcore();
123 return &rand_states[lcore_id];
129 struct rte_rand_state *state;
131 state = __rte_rand_get_state();
133 return __rte_rand_lfsr258(state);
136 RTE_INIT(rte_rand_init)
138 rte_srand(rte_get_timer_cycles());