| 142 | } |
| 143 | |
| 144 | uint64_t |
| 145 | rte_rand_max(uint64_t upper_bound) |
| 146 | { |
| 147 | struct rte_rand_state *state; |
| 148 | uint8_t ones; |
| 149 | uint8_t leading_zeros; |
| 150 | uint64_t mask = ~((uint64_t)0); |
| 151 | uint64_t res; |
| 152 | |
| 153 | if (unlikely(upper_bound < 2)) |
| 154 | return 0; |
| 155 | |
| 156 | state = __rte_rand_get_state(); |
| 157 | |
| 158 | ones = rte_popcount64(upper_bound); |
| 159 | |
| 160 | /* Handle power-of-2 upper_bound as a special case, since it |
| 161 | * has no bias issues. |
| 162 | */ |
| 163 | if (unlikely(ones == 1)) |
| 164 | return __rte_rand_lfsr258(state) & (upper_bound - 1); |
| 165 | |
| 166 | /* The approach to avoiding bias is to create a mask that |
| 167 | * stretches beyond the request value range, and up to the |
| 168 | * next power-of-2. In case the masked generated random value |
| 169 | * is equal to or greater than the upper bound, just discard |
| 170 | * the value and generate a new one. |
| 171 | */ |
| 172 | |
| 173 | leading_zeros = rte_clz64(upper_bound); |
| 174 | mask >>= leading_zeros; |
| 175 | |
| 176 | do { |
| 177 | res = __rte_rand_lfsr258(state) & mask; |
| 178 | } while (unlikely(res >= upper_bound)); |
| 179 | |
| 180 | return res; |
| 181 | } |
| 182 | |
| 183 | double |
| 184 | rte_drand(void) |