mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-03 17:58:30 +00:00
Fold LIBC_RAND into LIBC_STDIO/TINYMATH/INTRIN
This commit is contained in:
parent
05b8f82371
commit
8a0a2c0c36
183 changed files with 149 additions and 322 deletions
34
test/libc/stdio/devrand_test.c
Normal file
34
test/libc/stdio/devrand_test.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(getrandom, test) {
|
||||
void *A = gc(calloc(1, 8));
|
||||
void *B = gc(calloc(1, 8));
|
||||
EXPECT_EQ(8, getrandom(A, 8, 0));
|
||||
EXPECT_EQ(8, getrandom(B, 8, 0));
|
||||
EXPECT_BINNE(u" ", A);
|
||||
EXPECT_BINNE(u" ", B);
|
||||
EXPECT_NE(0, memcmp(A, B, 8));
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
|
243
test/libc/stdio/getrandom_test.c
Normal file
243
test/libc/stdio/getrandom_test.c
Normal file
|
@ -0,0 +1,243 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/stdio/lcg.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
/* JustReturnZero */
|
||||
/* entropy: 0 */
|
||||
/* chi-square: 2.55e+07 */
|
||||
/* chi-square percent: 0 */
|
||||
/* mean: 0 */
|
||||
/* monte-carlo-pi: 27.324 */
|
||||
/* serial-correlation: -100000 */
|
||||
|
||||
/* JustIncrement */
|
||||
/* entropy: 2.63951 */
|
||||
/* chi-square: 1.443e+07 */
|
||||
/* chi-square percent: 0 */
|
||||
/* mean: 18.8803 */
|
||||
/* monte-carlo-pi: 27.324 */
|
||||
/* serial-correlation: 0.0092003 */
|
||||
|
||||
/* UNIX Sixth Edition */
|
||||
/* entropy: 8 */
|
||||
/* chi-square: 0.1536 */
|
||||
/* chi-square percent: 1 */
|
||||
/* mean: 127.502 */
|
||||
/* monte-carlo-pi: 3.4192 */
|
||||
/* serial-correlation: -0.470645 */
|
||||
|
||||
/* UNIX Seventh Edition */
|
||||
/* entropy: 7.99818 */
|
||||
/* chi-square: 251.843 */
|
||||
/* chi-square percent: 0.544128 */
|
||||
/* mean: 127.955 */
|
||||
/* monte-carlo-pi: 0.675703 */
|
||||
/* serial-correlation: -0.00207669 */
|
||||
|
||||
/* KnuthLcg */
|
||||
/* entropy: 7.99835 */
|
||||
/* chi-square: 228.383 */
|
||||
/* chi-square percent: 0.883476 */
|
||||
/* mean: 127.1 */
|
||||
/* monte-carlo-pi: 0.561935 */
|
||||
/* serial-correlation: -0.0038954 */
|
||||
|
||||
/* rand64 */
|
||||
/* entropy: 7.99832 */
|
||||
/* chi-square: 233.267 */
|
||||
/* chi-square percent: 0.831821 */
|
||||
/* mean: 127.427 */
|
||||
/* monte-carlo-pi: 0.0271532 */
|
||||
/* serial-correlation: -0.00255319 */
|
||||
|
||||
/* Rand64LowByte */
|
||||
/* entropy: 7.99798 */
|
||||
/* chi-square: 278.344 */
|
||||
/* chi-square percent: 0.150796 */
|
||||
/* mean: 127.88 */
|
||||
/* monte-carlo-pi: 0.00340573 */
|
||||
/* serial-correlation: 0.00162231 */
|
||||
|
||||
/* GetRandomNoSystem */
|
||||
/* entropy: 7.99819 */
|
||||
/* chi-square: 249.743 */
|
||||
/* chi-square percent: 0.58114 */
|
||||
/* mean: 127.124 */
|
||||
/* monte-carlo-pi: 0.293716 */
|
||||
/* serial-correlation: 0.00198516 */
|
||||
|
||||
/* GetRandomNoRdrrnd */
|
||||
/* entropy: 7.99816 */
|
||||
/* chi-square: 254.797 */
|
||||
/* chi-square percent: 0.491811 */
|
||||
/* mean: 127.308 */
|
||||
/* monte-carlo-pi: 0.0118738 */
|
||||
/* serial-correlation: 0.000197669 */
|
||||
|
||||
/* GetRandom */
|
||||
/* entropy: 7.99808 */
|
||||
/* chi-square: 266.737 */
|
||||
/* chi-square percent: 0.294131 */
|
||||
/* mean: 127.178 */
|
||||
/* monte-carlo-pi: 0.0577122 */
|
||||
/* serial-correlation: 0.00598793 */
|
||||
|
||||
typedef uint64_t (*random_f)(void);
|
||||
|
||||
static uint32_t randx = 1;
|
||||
|
||||
uint64_t JustReturnZero(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t JustIncrement(void) {
|
||||
static uint64_t x;
|
||||
return x++;
|
||||
}
|
||||
|
||||
uint16_t SixthEditionRand(void) {
|
||||
static int16_t gorp;
|
||||
gorp = (gorp + 625) & 077777;
|
||||
return gorp;
|
||||
}
|
||||
|
||||
uint64_t SixthEditionLowByte(void) {
|
||||
unsigned i;
|
||||
uint64_t x;
|
||||
for (x = i = 0; i < 8; ++i) {
|
||||
x <<= 8;
|
||||
x |= SixthEditionRand() & 255;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t MobyDick(void) {
|
||||
static int i;
|
||||
if ((i += 8) > kMobySize) i = 8;
|
||||
return READ64LE(kMoby + i);
|
||||
}
|
||||
|
||||
uint64_t ExecutableImage(void) {
|
||||
static int i;
|
||||
if ((i += 8) > _end - _base) i = 8;
|
||||
return READ64LE(_base + i);
|
||||
}
|
||||
|
||||
uint32_t SeventhEditionRand(void) {
|
||||
return ((randx = randx * 1103515245 + 12345) >> 16) & 077777;
|
||||
}
|
||||
|
||||
uint64_t SeventhEditionLowByte(void) {
|
||||
unsigned i;
|
||||
uint64_t x;
|
||||
for (x = i = 0; i < 8; ++i) {
|
||||
x <<= 8;
|
||||
x |= SeventhEditionRand() & 255;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t KnuthLcg(void) {
|
||||
unsigned i;
|
||||
uint64_t x;
|
||||
for (x = i = 0; i < 8; ++i) {
|
||||
x <<= 8;
|
||||
x |= rand() & 255;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t Rand64LowByte(void) {
|
||||
unsigned i;
|
||||
uint64_t x;
|
||||
for (x = i = 0; i < 8; ++i) {
|
||||
x <<= 8;
|
||||
x |= rand64() & 255;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t GetRandom(void) {
|
||||
uint64_t x;
|
||||
ASSERT_EQ(8, getrandom(&x, 8, 0));
|
||||
return x;
|
||||
}
|
||||
|
||||
static const struct RandomFunction {
|
||||
const char *s;
|
||||
random_f f;
|
||||
bool r;
|
||||
} kRandomFunctions[] = {
|
||||
{"JustReturnZero", JustReturnZero, false}, //
|
||||
{"JustIncrement", JustIncrement, false}, //
|
||||
{"MobyDick", MobyDick, false}, //
|
||||
{"ExecutableImage", ExecutableImage, false}, //
|
||||
{"SixthEditionLowByte", SixthEditionLowByte, false}, //
|
||||
{"SeventhEditionLowByte", SeventhEditionLowByte, false}, //
|
||||
{"KnuthLcg", KnuthLcg, false}, //
|
||||
{"rand64", rand64, true}, //
|
||||
{"Rand64LowByte", Rand64LowByte, true}, //
|
||||
{"GetRandom", GetRandom, true}, //
|
||||
};
|
||||
|
||||
TEST(getrandom, sanityTest) {
|
||||
uint64_t q;
|
||||
size_t i, j, k;
|
||||
double montepi, chip, scc, mean, chisq, ent;
|
||||
for (k = 0; k < 1; ++k) {
|
||||
for (j = 0; j < ARRAYLEN(kRandomFunctions); ++j) {
|
||||
rt_init(0);
|
||||
for (i = 0; i + 8 <= 100000; i += 8) {
|
||||
q = kRandomFunctions[j].f();
|
||||
rt_add(&q, 8);
|
||||
}
|
||||
rt_end(&ent, &chisq, &mean, &montepi, &scc);
|
||||
chip = pochisq(chisq, 255);
|
||||
#if 0
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "/* %-32s */\n", kRandomFunctions[j].s);
|
||||
fprintf(stderr, "/* entropy: %-12g */\n", ent);
|
||||
fprintf(stderr, "/* chi-square: %-12g */\n", chisq);
|
||||
fprintf(stderr, "/* chi-square percent: %-12g */\n", chip);
|
||||
fprintf(stderr, "/* mean: %-12g */\n", mean);
|
||||
fprintf(stderr, "/* monte-carlo-pi: %-12g */\n",
|
||||
100 * fabs(M_PI - montepi) / M_PI);
|
||||
fprintf(stderr, "/* serial-correlation: %-12g */\n", scc);
|
||||
#endif
|
||||
if (kRandomFunctions[j].r) {
|
||||
CHECK_GT(chisq, 100, "%s", kRandomFunctions[j].s);
|
||||
CHECK_LT(chisq, 400, "%s", kRandomFunctions[j].s);
|
||||
CHECK_GE(ent * 10, 78, "%s", kRandomFunctions[j].s);
|
||||
CHECK_LT(fabs(scc) * 100, 5, "%s", kRandomFunctions[j].s);
|
||||
CHECK_LT(fabs(128 - mean), 3, "%s", kRandomFunctions[j].s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
215
test/libc/stdio/mt19937_test.c
Normal file
215
test/libc/stdio/mt19937_test.c
Normal file
|
@ -0,0 +1,215 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "third_party/mbedtls/ctr_drbg.h"
|
||||
|
||||
void GetRandom(void *p, size_t n) {
|
||||
ssize_t rc;
|
||||
size_t i, m;
|
||||
for (i = 0; i < n; i += rc) {
|
||||
m = MIN(n - i, 256);
|
||||
rc = getrandom((char *)p + i, m, 0);
|
||||
if (rc == -1 && errno == EINTR) continue;
|
||||
if (rc <= 0) abort();
|
||||
}
|
||||
}
|
||||
|
||||
int GetEntropy1(void *c, unsigned char *p, size_t n) {
|
||||
rngset(p, n, rdseed, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ctrdrbg1(void *p, size_t n) {
|
||||
int rc;
|
||||
size_t i, m;
|
||||
mbedtls_ctr_drbg_context rng;
|
||||
mbedtls_ctr_drbg_init(&rng);
|
||||
DCHECK_EQ(0, mbedtls_ctr_drbg_seed(&rng, GetEntropy1, 0, "justine", 7));
|
||||
for (i = 0; i < n; i += m) {
|
||||
m = MIN(n - i, MBEDTLS_CTR_DRBG_MAX_REQUEST);
|
||||
DCHECK_EQ(0, mbedtls_ctr_drbg_random(&rng, (unsigned char *)p + i, m));
|
||||
}
|
||||
mbedtls_ctr_drbg_free(&rng);
|
||||
}
|
||||
|
||||
int GetEntropy2(void *c, unsigned char *p, size_t n) {
|
||||
rngset(p, n, rdseed, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ctrdrbg2(void *p, size_t n) {
|
||||
int rc;
|
||||
size_t i, m;
|
||||
mbedtls_ctr_drbg_context rng;
|
||||
mbedtls_ctr_drbg_init(&rng);
|
||||
DCHECK_EQ(0, mbedtls_ctr_drbg_seed(&rng, GetEntropy2, 0, "justine", 7));
|
||||
for (i = 0; i < n; i += m) {
|
||||
m = MIN(n - i, MBEDTLS_CTR_DRBG_MAX_REQUEST);
|
||||
DCHECK_EQ(0, mbedtls_ctr_drbg_random(&rng, (unsigned char *)p + i, m));
|
||||
}
|
||||
mbedtls_ctr_drbg_free(&rng);
|
||||
}
|
||||
|
||||
dontinline uint64_t xorshift(void) {
|
||||
static uint64_t s = 88172645463325252;
|
||||
uint64_t x = s;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 7;
|
||||
x ^= x << 17;
|
||||
return (s = x);
|
||||
}
|
||||
|
||||
dontinline void xorshifta(char *p, size_t n) {
|
||||
static uint64_t s = 88172645463325252;
|
||||
uint64_t x = s;
|
||||
while (n >= 8) {
|
||||
x ^= x << 13;
|
||||
x ^= x >> 7;
|
||||
x ^= x << 17;
|
||||
__builtin_memcpy(p, &x, 8);
|
||||
n -= 8;
|
||||
p += 8;
|
||||
}
|
||||
s = x;
|
||||
while (n--) {
|
||||
*p++ = x;
|
||||
x >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
dontinline uint64_t knuth(void) {
|
||||
uint64_t a, b;
|
||||
static uint64_t x = 1;
|
||||
x *= 6364136223846793005;
|
||||
x += 1442695040888963407;
|
||||
a = x >> 32;
|
||||
x *= 6364136223846793005;
|
||||
x += 1442695040888963407;
|
||||
b = x >> 32;
|
||||
return a | b << 32;
|
||||
}
|
||||
|
||||
dontinline void knutha(char *p, size_t n) {
|
||||
static uint64_t s = 1;
|
||||
uint32_t u;
|
||||
uint64_t x = s;
|
||||
while (n >= 4) {
|
||||
x *= 6364136223846793005;
|
||||
x += 1442695040888963407;
|
||||
u = x >> 32;
|
||||
p[0] = (0x000000FF & u) >> 000;
|
||||
p[1] = (0x0000FF00 & u) >> 010;
|
||||
p[2] = (0x00FF0000 & u) >> 020;
|
||||
p[3] = (0xFF000000 & u) >> 030;
|
||||
n -= 4;
|
||||
p += 4;
|
||||
}
|
||||
s = x;
|
||||
while (n--) {
|
||||
*p++ = x;
|
||||
x >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t urandom(void) {
|
||||
return random();
|
||||
}
|
||||
|
||||
TEST(mt19937, test) {
|
||||
uint64_t init[] = {0x12345ULL, 0x23456ULL, 0x34567ULL, 0x45678ULL};
|
||||
uint64_t want[] = {
|
||||
7266447313870364031ull, 4946485549665804864ull, 16945909448695747420ull,
|
||||
16394063075524226720ull, 4873882236456199058ull,
|
||||
};
|
||||
_Smt19937(init, ARRAYLEN(init));
|
||||
for (int i = 0; i < ARRAYLEN(want); i++) {
|
||||
ASSERT_EQ(want[i], _mt19937());
|
||||
}
|
||||
}
|
||||
|
||||
BENCH(mt19937, bench8) {
|
||||
volatile uint64_t x;
|
||||
EZBENCH2("lemur64", donothing, x = lemur64());
|
||||
EZBENCH2("rand64", donothing, x = rand64());
|
||||
EZBENCH2("vigna", donothing, x = vigna());
|
||||
EZBENCH2("vigna_r", donothing, vigna_r(&x));
|
||||
EZBENCH2("xorshift", donothing, x = xorshift());
|
||||
EZBENCH2("knuth", donothing, x = knuth());
|
||||
EZBENCH2("random", donothing, x = urandom());
|
||||
EZBENCH2("mt19937", donothing, x = _mt19937());
|
||||
EZBENCH2("rand64char", donothing, x = rand64());
|
||||
size_t i = 0;
|
||||
volatile uint8_t *p = gc(malloc(3 * 2048 * 2 * 8));
|
||||
EZBENCH3("rdrand", 2048, donothing, p[i++] = rdrand());
|
||||
EZBENCH3("rdseed", 2048, donothing, p[i++] = rdseed());
|
||||
EZBENCH3("getrandom", 2048, donothing, GetRandom(p + i++, 8));
|
||||
}
|
||||
|
||||
BENCH(mt19937, bench32k) {
|
||||
volatile char *p = gc(malloc(32768));
|
||||
EZBENCH_N("rngset(rand64,-1)", 32768, rngset(p, 32768, rand64, -1));
|
||||
EZBENCH_N("rngset(rdseed,512)", 32768, rngset(p, 32768, rdseed, 512));
|
||||
EZBENCH_N("ctrdrbg+rdseed [blk]", 32768, ctrdrbg1(p, 32768));
|
||||
EZBENCH_N("getrandom [block]", 32768, GetRandom(p, 32768));
|
||||
EZBENCH_N("vigna [word]", 32768, rngset(p, 32768, vigna, 0));
|
||||
EZBENCH_N("xorshift [word]", 32768, xorshifta(p, 32768));
|
||||
EZBENCH_N("knuth [word]", 32768, knutha(p, 32768));
|
||||
EZBENCH_N("random [word]", 32768, rngset(p, 32768, urandom, 0));
|
||||
EZBENCH_N("mt19937 [word]", 32768, rngset(p, 32768, _mt19937, 0));
|
||||
EZBENCH_N("rand64 [word]", 32768, rngset(p, 32768, rand64, 0));
|
||||
EZBENCH_N("rdrand [word]", 32768, rngset(p, 32768, rdrand, 0));
|
||||
EZBENCH_N("rdseed [word]", 32768, rngset(p, 32768, rdseed, 0));
|
||||
}
|
||||
|
||||
BENCH(mt19937, bench48) {
|
||||
volatile char *p = gc(malloc(48));
|
||||
EZBENCH_N("rngset(rdrand,0)", 48, rngset(p, 48, rdrand, 0));
|
||||
EZBENCH_N("rngset(rdseed,0)", 48, rngset(p, 48, rdseed, 0));
|
||||
EZBENCH_N("getrandom", 48, GetRandom(p, 48));
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(mt19937, test) {
|
||||
int i;
|
||||
uint64_t init[4] = {0x12345ULL, 0x23456ULL, 0x34567ULL, 0x45678ULL};
|
||||
uint64_t length = 4;
|
||||
mt19937_init_by_array64(init, length);
|
||||
printf("1000 outputs of genrand64_int64()\n");
|
||||
for (i = 0; i < 1000; i++) {
|
||||
printf("%20llu ", mt19937_genrand64_int64());
|
||||
if (i % 5 == 4) printf("\n");
|
||||
}
|
||||
printf("\n1000 outputs of genrand64_real2()\n");
|
||||
for (i = 0; i < 1000; i++) {
|
||||
printf("%10.8f ", mt19937_genrand64_real2());
|
||||
if (i % 5 == 4) printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
55
test/libc/stdio/rand_test.c
Normal file
55
test/libc/stdio/rand_test.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(rand002, alwaysReturnsPositiveNumbers) {
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
ASSERT_GT(rand(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(rand003, srandSmokeTest) {
|
||||
srand(1);
|
||||
ASSERT_EQ(908834774, rand());
|
||||
srand(1);
|
||||
ASSERT_EQ(908834774, rand());
|
||||
srand(7);
|
||||
ASSERT_EQ(1059165278, rand());
|
||||
}
|
||||
|
||||
TEST(rand005, rand64SmokeTest) {
|
||||
ASSERT_TRUE(rand64() != rand64() || rand64() != rand64());
|
||||
}
|
||||
|
||||
TEST(rand64, test) {
|
||||
char *p;
|
||||
size_t i;
|
||||
uint64_t x;
|
||||
p = memcpy(malloc(kHyperionSize), kHyperion, kHyperionSize);
|
||||
for (i = 0; i < kHyperionSize / 8; ++i) {
|
||||
x = rand64();
|
||||
WRITE64LE(p + i * 8, x);
|
||||
}
|
||||
free(p);
|
||||
}
|
67
test/libc/stdio/rngset_test.c
Normal file
67
test/libc/stdio/rngset_test.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
uint64_t counter(void) {
|
||||
static uint8_t t;
|
||||
return 0x0101010101010101ull * t++;
|
||||
}
|
||||
|
||||
TEST(rngset, testZeroReseedInterval_doesntApplyPrng) {
|
||||
char buf[32];
|
||||
EXPECT_EQ(buf, rngset(buf, sizeof(buf), counter, 0));
|
||||
EXPECT_EQ(0x0000000000000000, READ64LE(buf + 0));
|
||||
EXPECT_EQ(0x0101010101010101, READ64LE(buf + 8));
|
||||
EXPECT_EQ(0x0202020202020202, READ64LE(buf + 16));
|
||||
EXPECT_EQ(0x0303030303030303, READ64LE(buf + 24));
|
||||
}
|
||||
|
||||
uint64_t eleet(void) {
|
||||
return 0x31337;
|
||||
}
|
||||
|
||||
TEST(rngset, testReseedIsNeg_usesInternalVignaPrng) {
|
||||
char buf[32];
|
||||
svigna(0x31337);
|
||||
EXPECT_EQ(buf, rngset(buf, sizeof(buf), eleet, -1));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 0));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 8));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 16));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 24));
|
||||
}
|
||||
|
||||
TEST(rngset, testNullSeedFunction_reseedBecomesVignaSeed) {
|
||||
char buf[32];
|
||||
svigna(123);
|
||||
EXPECT_EQ(buf, rngset(buf, sizeof(buf), 0, 123));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 0));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 8));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 16));
|
||||
EXPECT_EQ(vigna(), READ64LE(buf + 24));
|
||||
}
|
||||
|
||||
TEST(rngset, testWeirdlyShaped_doesntCrash) {
|
||||
char buf[7];
|
||||
rngset(buf, sizeof(buf), 0, 0);
|
||||
rngset(buf, sizeof(buf), vigna, 0);
|
||||
rngset(buf, sizeof(buf), vigna, 9);
|
||||
rngset(buf, sizeof(buf), vigna, 8);
|
||||
}
|
|
@ -28,7 +28,6 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
|
|||
LIBC_INTRIN \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
|
@ -43,6 +42,7 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
|
|||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_ZLIB_GZ
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue