diff options
Diffstat (limited to 'libc-top-half/musl/src/prng')
-rw-r--r-- | libc-top-half/musl/src/prng/__rand48_step.c | 14 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/__seed48.c | 3 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/drand48.c | 17 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/lcong48.c | 8 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/lrand48.c | 13 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/mrand48.c | 13 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/rand.c | 15 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/rand48.h | 5 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/rand_r.c | 15 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/random.c | 126 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/seed48.c | 11 | ||||
-rw-r--r-- | libc-top-half/musl/src/prng/srand48.c | 6 |
12 files changed, 246 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/prng/__rand48_step.c b/libc-top-half/musl/src/prng/__rand48_step.c new file mode 100644 index 0000000..94703d0 --- /dev/null +++ b/libc-top-half/musl/src/prng/__rand48_step.c @@ -0,0 +1,14 @@ +#include <stdint.h> +#include "rand48.h" + +uint64_t __rand48_step(unsigned short *xi, unsigned short *lc) +{ + uint64_t a, x; + x = xi[0] | xi[1]+0U<<16 | xi[2]+0ULL<<32; + a = lc[0] | lc[1]+0U<<16 | lc[2]+0ULL<<32; + x = a*x + lc[3]; + xi[0] = x; + xi[1] = x>>16; + xi[2] = x>>32; + return x & 0xffffffffffffull; +} diff --git a/libc-top-half/musl/src/prng/__seed48.c b/libc-top-half/musl/src/prng/__seed48.c new file mode 100644 index 0000000..e436b4d --- /dev/null +++ b/libc-top-half/musl/src/prng/__seed48.c @@ -0,0 +1,3 @@ +#include "rand48.h" + +unsigned short __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb }; diff --git a/libc-top-half/musl/src/prng/drand48.c b/libc-top-half/musl/src/prng/drand48.c new file mode 100644 index 0000000..08283e2 --- /dev/null +++ b/libc-top-half/musl/src/prng/drand48.c @@ -0,0 +1,17 @@ +#include <stdlib.h> +#include <inttypes.h> +#include "rand48.h" + +double erand48(unsigned short s[3]) +{ + union { + uint64_t u; + double f; + } x = { 0x3ff0000000000000ULL | __rand48_step(s, __seed48+3)<<4 }; + return x.f - 1.0; +} + +double drand48(void) +{ + return erand48(__seed48); +} diff --git a/libc-top-half/musl/src/prng/lcong48.c b/libc-top-half/musl/src/prng/lcong48.c new file mode 100644 index 0000000..030e514 --- /dev/null +++ b/libc-top-half/musl/src/prng/lcong48.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#include <string.h> +#include "rand48.h" + +void lcong48(unsigned short p[7]) +{ + memcpy(__seed48, p, sizeof __seed48); +} diff --git a/libc-top-half/musl/src/prng/lrand48.c b/libc-top-half/musl/src/prng/lrand48.c new file mode 100644 index 0000000..07e2b78 --- /dev/null +++ b/libc-top-half/musl/src/prng/lrand48.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#include <inttypes.h> +#include "rand48.h" + +long nrand48(unsigned short s[3]) +{ + return __rand48_step(s, __seed48+3) >> 17; +} + +long lrand48(void) +{ + return nrand48(__seed48); +} diff --git a/libc-top-half/musl/src/prng/mrand48.c b/libc-top-half/musl/src/prng/mrand48.c new file mode 100644 index 0000000..f4a56e6 --- /dev/null +++ b/libc-top-half/musl/src/prng/mrand48.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#include <inttypes.h> +#include "rand48.h" + +long jrand48(unsigned short s[3]) +{ + return (int32_t)(__rand48_step(s, __seed48+3) >> 16); +} + +long mrand48(void) +{ + return jrand48(__seed48); +} diff --git a/libc-top-half/musl/src/prng/rand.c b/libc-top-half/musl/src/prng/rand.c new file mode 100644 index 0000000..c000cd2 --- /dev/null +++ b/libc-top-half/musl/src/prng/rand.c @@ -0,0 +1,15 @@ +#include <stdlib.h> +#include <stdint.h> + +static uint64_t seed; + +void srand(unsigned s) +{ + seed = s-1; +} + +int rand(void) +{ + seed = 6364136223846793005ULL*seed + 1; + return seed>>33; +} diff --git a/libc-top-half/musl/src/prng/rand48.h b/libc-top-half/musl/src/prng/rand48.h new file mode 100644 index 0000000..55cbec1 --- /dev/null +++ b/libc-top-half/musl/src/prng/rand48.h @@ -0,0 +1,5 @@ +#include <stdint.h> +#include <features.h> + +hidden uint64_t __rand48_step(unsigned short *xi, unsigned short *lc); +extern hidden unsigned short __seed48[7]; diff --git a/libc-top-half/musl/src/prng/rand_r.c b/libc-top-half/musl/src/prng/rand_r.c new file mode 100644 index 0000000..638614c --- /dev/null +++ b/libc-top-half/musl/src/prng/rand_r.c @@ -0,0 +1,15 @@ +#include <stdlib.h> + +static unsigned temper(unsigned x) +{ + x ^= x>>11; + x ^= x<<7 & 0x9D2C5680; + x ^= x<<15 & 0xEFC60000; + x ^= x>>18; + return x; +} + +int rand_r(unsigned *seed) +{ + return temper(*seed = *seed * 1103515245 + 12345)/2; +} diff --git a/libc-top-half/musl/src/prng/random.c b/libc-top-half/musl/src/prng/random.c new file mode 100644 index 0000000..daac028 --- /dev/null +++ b/libc-top-half/musl/src/prng/random.c @@ -0,0 +1,126 @@ +#include <stdlib.h> +#include <stdint.h> +#include "lock.h" +#include "fork_impl.h" + +/* +this code uses the same lagged fibonacci generator as the +original bsd random implementation except for the seeding +which was broken in the original +*/ + +static uint32_t init[] = { +0x00000000,0x5851f42d,0xc0b18ccf,0xcbb5f646, +0xc7033129,0x30705b04,0x20fd5db4,0x9a8b7f78, +0x502959d8,0xab894868,0x6c0356a7,0x88cdb7ff, +0xb477d43f,0x70a3a52b,0xa8e4baf1,0xfd8341fc, +0x8ae16fd9,0x742d2f7a,0x0d1f0796,0x76035e09, +0x40f7702c,0x6fa72ca5,0xaaa84157,0x58a0df74, +0xc74a0364,0xae533cc4,0x04185faf,0x6de3b115, +0x0cab8628,0xf043bfa4,0x398150e9,0x37521657}; + +static int n = 31; +static int i = 3; +static int j = 0; +static uint32_t *x = init+1; +#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) +static volatile int lock[1]; +volatile int *const __random_lockptr = lock; +#endif + +static uint32_t lcg31(uint32_t x) { + return (1103515245*x + 12345) & 0x7fffffff; +} + +static uint64_t lcg64(uint64_t x) { + return 6364136223846793005ull*x + 1; +} + +static void *savestate() { + x[-1] = (n<<16)|(i<<8)|j; + return x-1; +} + +static void loadstate(uint32_t *state) { + x = state+1; + n = x[-1]>>16; + i = (x[-1]>>8)&0xff; + j = x[-1]&0xff; +} + +static void __srandom(unsigned seed) { + int k; + uint64_t s = seed; + + if (n == 0) { + x[0] = s; + return; + } + i = n == 31 || n == 7 ? 3 : 1; + j = 0; + for (k = 0; k < n; k++) { + s = lcg64(s); + x[k] = s>>32; + } + /* make sure x contains at least one odd number */ + x[0] |= 1; +} + +void srandom(unsigned seed) { + LOCK(lock); + __srandom(seed); + UNLOCK(lock); +} + +char *initstate(unsigned seed, char *state, size_t size) { + void *old; + + if (size < 8) + return 0; + LOCK(lock); + old = savestate(); + if (size < 32) + n = 0; + else if (size < 64) + n = 7; + else if (size < 128) + n = 15; + else if (size < 256) + n = 31; + else + n = 63; + x = (uint32_t*)state + 1; + __srandom(seed); + savestate(); + UNLOCK(lock); + return old; +} + +char *setstate(char *state) { + void *old; + + LOCK(lock); + old = savestate(); + loadstate((uint32_t*)state); + UNLOCK(lock); + return old; +} + +long random(void) { + long k; + + LOCK(lock); + if (n == 0) { + k = x[0] = lcg31(x[0]); + goto end; + } + x[i] += x[j]; + k = x[i]>>1; + if (++i == n) + i = 0; + if (++j == n) + j = 0; +end: + UNLOCK(lock); + return k; +} diff --git a/libc-top-half/musl/src/prng/seed48.c b/libc-top-half/musl/src/prng/seed48.c new file mode 100644 index 0000000..bce7b33 --- /dev/null +++ b/libc-top-half/musl/src/prng/seed48.c @@ -0,0 +1,11 @@ +#include <stdlib.h> +#include <string.h> +#include "rand48.h" + +unsigned short *seed48(unsigned short *s) +{ + static unsigned short p[3]; + memcpy(p, __seed48, sizeof p); + memcpy(__seed48, s, sizeof p); + return p; +} diff --git a/libc-top-half/musl/src/prng/srand48.c b/libc-top-half/musl/src/prng/srand48.c new file mode 100644 index 0000000..0a56f6a --- /dev/null +++ b/libc-top-half/musl/src/prng/srand48.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +void srand48(long seed) +{ + seed48((unsigned short [3]){ 0x330e, seed, seed>>16 }); +} |