From: Kent Overstreet Date: Tue, 27 Jun 2023 23:45:40 +0000 (-0400) Subject: get_random_u32_below() X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=619c99de4be8f0618e7c4cb65039de2aa1e2536c;p=bcachefs-tools-debian get_random_u32_below() Signed-off-by: Kent Overstreet --- diff --git a/include/linux/random.h b/include/linux/random.h index ea101d5..3203d13 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef SYS_getrandom static inline int getrandom(void *buf, size_t buflen, unsigned int flags) @@ -40,7 +41,30 @@ static inline type get_random_##type(void) \ get_random_type(int); get_random_type(long); +get_random_type(u8); +get_random_type(u16); get_random_type(u32); get_random_type(u64); +static inline u32 get_random_u32_below(u32 ceil) +{ + if (ceil <= 1) + return 0; + for (;;) { + if (ceil <= 1U << 8) { + u32 mult = ceil * get_random_u8(); + if (likely(is_power_of_2(ceil) || (u8)mult >= (1U << 8) % ceil)) + return mult >> 8; + } else if (ceil <= 1U << 16) { + u32 mult = ceil * get_random_u16(); + if (likely(is_power_of_2(ceil) || (u16)mult >= (1U << 16) % ceil)) + return mult >> 16; + } else { + u64 mult = (u64)ceil * get_random_u32(); + if (likely(is_power_of_2(ceil) || (u32)mult >= -ceil % ceil)) + return mult >> 32; + } + } +} + #endif /* _LINUX_RANDOM_H */