#include "iso_alloc_internal.h"
#define OLD_GLIBC (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 24)
#if OLD_GLIBC
#include <linux/random.h>
#include <sys/syscall.h>
#elif __APPLE__
#include <Security/SecRandom.h>
#elif __FreeBSD__ || __DragonFly__ || __linux__ || __ANDROID__
#include <sys/random.h>
#elif __NetBSD__
#include <stdlib.h>
#elif __sun
#include <sys/random.h>
#else
#error "unknown OS"
#endif
INTERNAL_HIDDEN INLINE uint64_t us_rand_uint64(uint64_t *seed) {
*seed += 0x5d6447c8df9375b5;
__uint128_t tmp = (__uint128_t) *seed * 0x3c5829f2fb3c3eef;
uint64_t m1 = (tmp >> 64) ^ tmp;
tmp = (__uint128_t) m1 * 0x4f38e4ccc1b0ea59;
return (tmp >> 64) ^ tmp;
}
INTERNAL_HIDDEN INLINE uint64_t rand_uint64(void) {
uint64_t val = 0;
int ret = 0;
#if OLD_GLIBC
ret = syscall(SYS_getrandom, &val, sizeof(val), GRND_NONBLOCK) != sizeof(val);
#elif __APPLE__
ret = SecRandomCopyBytes(kSecRandomDefault, sizeof(val), &val);
#elif __FreeBSD__ || __DragonFly__ || __linux__ || __ANDROID__ || __sun
ret = getrandom(&val, sizeof(val), GRND_NONBLOCK) != sizeof(val);
#elif __NetBSD__
arc4random_buf(&val, sizeof(val));
#endif
#if ABORT_NO_ENTROPY
if(ret != 0) {
LOG_AND_ABORT("Unable to gather enough entropy");
}
#endif
return val;
}