mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
New pseudo random number generator
This commit is contained in:
parent
0aafcd1819
commit
13fae39eb3
6 changed files with 80 additions and 33 deletions
|
|
@ -163,13 +163,10 @@ void os_init(int opt)
|
|||
/* check for Wine presence */
|
||||
is_wine = GetProcAddress(ntdll, "wine_get_version") != 0;
|
||||
|
||||
/* setup the standard random generator used as fallback */
|
||||
srand(GetTickCount());
|
||||
|
||||
/* get pointer to RtlGenRandom, note that it was reported missing in some cases */
|
||||
ptr_RtlGenRandom = (void*)GetProcAddress(dll_advapi32, "SystemFunction036");
|
||||
|
||||
/* get pointer to RtlGenRandom, note that it was reported missing in some cases */
|
||||
/* get pointer to ptr_GetTickCount64 */
|
||||
ptr_GetTickCount64 = (void*)GetProcAddress(kernel32, "GetTickCount64");
|
||||
|
||||
/* set the thread execution level to avoid sleep */
|
||||
|
|
@ -2239,21 +2236,9 @@ int randomize(void* void_ptr, size_t size)
|
|||
if (ptr_RtlGenRandom != 0 && ptr_RtlGenRandom(ptr, size) != 0)
|
||||
return 0;
|
||||
|
||||
/* try rand_s */
|
||||
for (i = 0; i < size; ++i) {
|
||||
unsigned v = 0;
|
||||
|
||||
if (rand_s(&v) != 0)
|
||||
break;
|
||||
|
||||
ptr[i] = v;
|
||||
}
|
||||
if (i == size)
|
||||
return 0;
|
||||
|
||||
/* fallback to standard rand */
|
||||
for (i = 0; i < size; ++i)
|
||||
ptr[i] = rand();
|
||||
ptr[i] = random_u8();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,11 +46,6 @@
|
|||
*/
|
||||
#define _WIN32_WINNT 0x600
|
||||
|
||||
/**
|
||||
* Enable the rand_s() function.l
|
||||
*/
|
||||
#define _CRT_RAND_S
|
||||
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
os_init(opt.force_scan_winfind);
|
||||
raid_init();
|
||||
crc32c_init();
|
||||
random_reseed();
|
||||
|
||||
if (speedtest != 0) {
|
||||
speed(period);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#if HAVE_THREAD
|
||||
static thread_mutex_t msg_lock;
|
||||
static thread_mutex_t memory_lock;
|
||||
static thread_mutex_t random_lock;
|
||||
#endif
|
||||
|
||||
void lock_msg(void)
|
||||
|
|
@ -58,12 +59,28 @@ void unlock_memory(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
void lock_random(void)
|
||||
{
|
||||
#if HAVE_THREAD
|
||||
thread_mutex_lock(&random_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void unlock_random(void)
|
||||
{
|
||||
#if HAVE_THREAD
|
||||
thread_mutex_unlock(&random_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void lock_init(void)
|
||||
{
|
||||
#if HAVE_THREAD
|
||||
/* initialize the locks as first operation as log_fatal depends on them */
|
||||
thread_mutex_init(&msg_lock);
|
||||
thread_mutex_init(&memory_lock);
|
||||
thread_mutex_init(&random_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -72,9 +89,50 @@ void lock_done(void)
|
|||
#if HAVE_THREAD
|
||||
thread_mutex_destroy(&msg_lock);
|
||||
thread_mutex_destroy(&memory_lock);
|
||||
thread_mutex_destroy(&random_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* random */
|
||||
|
||||
static uint64_t random_state = 1;
|
||||
|
||||
void random_reseed(void)
|
||||
{
|
||||
random_state = tick();
|
||||
}
|
||||
|
||||
unsigned char random_u8(void)
|
||||
{
|
||||
return random_u64() & 0xFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* SplitMix64
|
||||
*
|
||||
* - Zero-safe: Any 64-bit seed is valid (even 0).
|
||||
* - Full period: Guaranteed to visit every 2^64 value.
|
||||
* - Logic: Uses a Weyl sequence + MurmurHash3-style finalizer.
|
||||
*
|
||||
* See: https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64
|
||||
*/
|
||||
uint64_t random_u64(void)
|
||||
{
|
||||
uint64_t z;
|
||||
|
||||
lock_random();
|
||||
|
||||
z = random_state += 0x9E3779B97F4A7C15ULL;
|
||||
|
||||
unlock_random();
|
||||
|
||||
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL;
|
||||
z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL;
|
||||
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* print */
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,24 @@ void unlock_msg(void);
|
|||
void lock_memory(void);
|
||||
void unlock_memory(void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* random */
|
||||
|
||||
/**
|
||||
* Reseed the random pseudo random number generator
|
||||
*/
|
||||
void random_reseed(void);
|
||||
|
||||
/**
|
||||
* Return a pseudo random number of 8 bits
|
||||
*/
|
||||
unsigned char random_u8(void);
|
||||
|
||||
/**
|
||||
* Return a pseudo random number of 64 bits
|
||||
*/
|
||||
uint64_t random_u64(void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* log */
|
||||
|
||||
|
|
|
|||
|
|
@ -1622,16 +1622,6 @@ static int devup(dev_t device, const char* name)
|
|||
void* buf;
|
||||
uint64_t size;
|
||||
uint64_t offset;
|
||||
uint64_t pseudo_random;
|
||||
|
||||
/* get a pseudo random number */
|
||||
ret = randomize(&pseudo_random, sizeof(pseudo_random));
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed to retrieve random values.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (devresolve(device, file, sizeof(file)) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
@ -1669,7 +1659,7 @@ static int devup(dev_t device, const char* name)
|
|||
}
|
||||
|
||||
/* select a random offset */
|
||||
offset = (pseudo_random % (size / 4096)) * 4096;
|
||||
offset = (random_u64() % (size / 4096)) * 4096;
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* clear cache */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue