util: introduce kernel utils for pseudorandom number generation
Currently there are two generators. The fast one is the same one the scheduler is using. The standard one is the same algorithm libroot's rand() uses. Should there be a need for more cryptographically PRNG MD4 or MD5 might be a good candidates.
This commit is contained in:
parent
feae2b5a00
commit
6003243ef3
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_RANDOM_H
|
||||
#define KERNEL_UTIL_RANDOM_H
|
||||
|
||||
|
||||
#include <smp.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#define MAX_FAST_RANDOM_VALUE 0x7fff
|
||||
#define MAX_RANDOM_VALUE 0x7fffffffu
|
||||
|
||||
const int kFastRandomShift = 15;
|
||||
const int kRandomShift = 31;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
unsigned int fast_random_value(void);
|
||||
unsigned int random_value(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
template<typename T>
|
||||
T
|
||||
fast_get_random()
|
||||
{
|
||||
size_t shift = 0;
|
||||
T random = 0;
|
||||
while (shift < sizeof(T) * 8) {
|
||||
random |= (T)fast_random_value() << shift;
|
||||
shift += kFastRandomShift;
|
||||
}
|
||||
|
||||
return random;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
T
|
||||
get_random()
|
||||
{
|
||||
size_t shift = 0;
|
||||
T random = 0;
|
||||
while (shift < sizeof(T) * 8) {
|
||||
random |= (T)random_value() << shift;
|
||||
shift += kRandomShift;
|
||||
}
|
||||
|
||||
return random;
|
||||
}
|
||||
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // KERNEL_UTIL_RANDOM_H
|
||||
|
|
@ -14,6 +14,7 @@ KernelMergeObject kernel_util.o :
|
|||
queue.cpp
|
||||
ring_buffer.cpp
|
||||
RadixBitmap.cpp
|
||||
Random.cpp
|
||||
|
||||
: $(TARGET_KERNEL_PIC_CCFLAGS) -DUSING_LIBGCC
|
||||
;
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
|
||||
|
||||
#include <util/Random.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
static uint32 fast_last = 0;
|
||||
static uint32 last = 0;
|
||||
|
||||
// In the following functions there are race conditions when many threads
|
||||
// attempt to update static variable last. However, since such conflicts
|
||||
// are non-deterministic it is not a big problem.
|
||||
|
||||
|
||||
// A simple linear congruential generator
|
||||
unsigned int
|
||||
fast_random_value()
|
||||
{
|
||||
if (fast_last == 0)
|
||||
fast_last = system_time();
|
||||
|
||||
uint32 random = fast_last * 1103515245 + 12345;
|
||||
fast_last = random;
|
||||
return (random >> 16) & 0x7fff;
|
||||
}
|
||||
|
||||
|
||||
// Taken from "Random number generators: good ones are hard to find",
|
||||
// Park and Miller, Communications of the ACM, vol. 31, no. 10,
|
||||
// October 1988, p. 1195.
|
||||
unsigned int
|
||||
random_value()
|
||||
{
|
||||
if (last == 0)
|
||||
last = system_time();
|
||||
|
||||
uint32 hi = last / 127773;
|
||||
uint32 lo = last % 127773;
|
||||
|
||||
int32 random = 16807 * lo - 2836 * hi;
|
||||
if (random <= 0)
|
||||
random += MAX_RANDOM_VALUE;
|
||||
last = random;
|
||||
return random % (MAX_RANDOM_VALUE + 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue