aboutsummaryrefslogtreecommitdiff
path: root/contrib/bc/src/rand.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bc/src/rand.c')
-rw-r--r--contrib/bc/src/rand.c201
1 files changed, 128 insertions, 73 deletions
diff --git a/contrib/bc/src/rand.c b/contrib/bc/src/rand.c
index a3b8942a6042..560e494214ad 100644
--- a/contrib/bc/src/rand.c
+++ b/contrib/bc/src/rand.c
@@ -13,7 +13,7 @@
* This code is under the following license:
*
* Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
- * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -66,8 +66,9 @@
* @param b The second operand.
* @return The sum, including overflow.
*/
-static BcRandState bc_rand_addition(uint_fast64_t a, uint_fast64_t b) {
-
+static BcRandState
+bc_rand_addition(uint_fast64_t a, uint_fast64_t b)
+{
BcRandState res;
res.lo = a + b;
@@ -82,8 +83,9 @@ static BcRandState bc_rand_addition(uint_fast64_t a, uint_fast64_t b) {
* @param b The second operand.
* @return The sum, without overflow.
*/
-static BcRandState bc_rand_addition2(BcRandState a, BcRandState b) {
-
+static BcRandState
+bc_rand_addition2(BcRandState a, BcRandState b)
+{
BcRandState temp, res;
res = bc_rand_addition(a.lo, b.lo);
@@ -99,8 +101,9 @@ static BcRandState bc_rand_addition2(BcRandState a, BcRandState b) {
* @param b The second operand.
* @return The product, including overflow.
*/
-static BcRandState bc_rand_multiply(uint_fast64_t a, uint_fast64_t b) {
-
+static BcRandState
+bc_rand_multiply(uint_fast64_t a, uint_fast64_t b)
+{
uint_fast64_t al, ah, bl, bh, c0, c1, c2, c3;
BcRandState carry, res;
@@ -128,8 +131,9 @@ static BcRandState bc_rand_multiply(uint_fast64_t a, uint_fast64_t b) {
* @param b The second operand.
* @return The product, without overflow.
*/
-static BcRandState bc_rand_multiply2(BcRandState a, BcRandState b) {
-
+static BcRandState
+bc_rand_multiply2(BcRandState a, BcRandState b)
+{
BcRandState c0, c1, c2, carry;
c0 = bc_rand_multiply(a.lo, b.lo);
@@ -150,8 +154,9 @@ static BcRandState bc_rand_multiply2(BcRandState a, BcRandState b) {
* stack of PRNG's.
* @param r The PRNG to mark as modified.
*/
-static void bc_rand_setModified(BcRNGData *r) {
-
+static void
+bc_rand_setModified(BcRNGData* r)
+{
#if BC_RAND_BUILTIN
r->inc |= (BcRandState) 1UL;
#else // BC_RAND_BUILTIN
@@ -164,8 +169,9 @@ static void bc_rand_setModified(BcRNGData *r) {
* stack of PRNG's.
* @param r The PRNG to mark as not modified.
*/
-static void bc_rand_clearModified(BcRNGData *r) {
-
+static void
+bc_rand_clearModified(BcRNGData* r)
+{
#if BC_RAND_BUILTIN
r->inc &= ~((BcRandState) 1UL);
#else // BC_RAND_BUILTIN
@@ -179,9 +185,14 @@ static void bc_rand_clearModified(BcRNGData *r) {
* @param d The destination PRNG.
* @param s The source PRNG.
*/
-static void bc_rand_copy(BcRNGData *d, BcRNGData *s) {
+static void
+bc_rand_copy(BcRNGData* d, BcRNGData* s)
+{
bool unmod = BC_RAND_NOTMODIFIED(d);
+
+ // NOLINTNEXTLINE
memcpy(d, s, sizeof(BcRNGData));
+
if (!unmod) bc_rand_setModified(d);
else if (!BC_RAND_NOTMODIFIED(s)) bc_rand_clearModified(d);
}
@@ -193,21 +204,22 @@ static void bc_rand_copy(BcRNGData *d, BcRNGData *s) {
* @param ptr A pointer to the file, as a void pointer.
* @return The random data as an unsigned long.
*/
-static ulong bc_rand_frand(void* ptr) {
-
+static ulong
+bc_rand_frand(void* ptr)
+{
ulong buf[1];
int fd;
ssize_t nread;
assert(ptr != NULL);
- fd = *((int*)ptr);
+ fd = *((int*) ptr);
nread = read(fd, buf, sizeof(ulong));
if (BC_ERR(nread != sizeof(ulong))) bc_vm_fatalError(BC_ERR_FATAL_IO_ERR);
- return *((ulong*)buf);
+ return *((ulong*) buf);
}
#else // _WIN32
@@ -216,8 +228,9 @@ static ulong bc_rand_frand(void* ptr) {
* @param ptr An unused parameter.
* @return The random data as an unsigned long.
*/
-static ulong bc_rand_winrand(void *ptr) {
-
+static ulong
+bc_rand_winrand(void* ptr)
+{
ulong buf[1];
NTSTATUS s;
@@ -242,8 +255,9 @@ static ulong bc_rand_winrand(void *ptr) {
* @param ptr An unused parameter.
* @return The random data as an unsigned long.
*/
-static ulong bc_rand_rand(void *ptr) {
-
+static ulong
+bc_rand_rand(void* ptr)
+{
size_t i;
ulong res = 0;
@@ -251,7 +265,9 @@ static ulong bc_rand_rand(void *ptr) {
// Fill up the unsigned long byte-by-byte.
for (i = 0; i < sizeof(ulong); ++i)
+ {
res |= ((ulong) (rand() & BC_RAND_SRAND_BITS)) << (i * CHAR_BIT);
+ }
return res;
}
@@ -262,8 +278,9 @@ static ulong bc_rand_rand(void *ptr) {
* @param r The PRNG.
* @return The increment of the PRNG, including the last odd bit.
*/
-static BcRandState bc_rand_inc(BcRNGData *r) {
-
+static BcRandState
+bc_rand_inc(BcRNGData* r)
+{
BcRandState inc;
#if BC_RAND_BUILTIN
@@ -280,8 +297,9 @@ static BcRandState bc_rand_inc(BcRNGData *r) {
* Sets up the increment for the PRNG.
* @param r The PRNG whose increment will be set up.
*/
-static void bc_rand_setupInc(BcRNGData *r) {
-
+static void
+bc_rand_setupInc(BcRNGData* r)
+{
#if BC_RAND_BUILTIN
r->inc <<= 1UL;
#else // BC_RAND_BUILTIN
@@ -297,8 +315,9 @@ static void bc_rand_setupInc(BcRNGData *r) {
* @param val1 The lower half of the state.
* @param val2 The upper half of the state.
*/
-static void bc_rand_seedState(BcRandState *state, ulong val1, ulong val2) {
-
+static void
+bc_rand_seedState(BcRandState* state, ulong val1, ulong val2)
+{
#if BC_RAND_BUILTIN
*state = ((BcRandState) val1) | ((BcRandState) val2) << (BC_LONG_BIT);
#else // BC_RAND_BUILTIN
@@ -315,8 +334,9 @@ static void bc_rand_seedState(BcRandState *state, ulong val1, ulong val2) {
* @param inc1 The lower half of the increment.
* @param inc2 The upper half of the increment.
*/
-static void bc_rand_seedRNG(BcRNGData *r, ulong state1, ulong state2,
- ulong inc1, ulong inc2)
+static void
+bc_rand_seedRNG(BcRNGData* r, ulong state1, ulong state2, ulong inc1,
+ ulong inc2)
{
bc_rand_seedState(&r->state, state1, state2);
bc_rand_seedState(&r->inc, inc1, inc2);
@@ -329,8 +349,9 @@ static void bc_rand_seedRNG(BcRNGData *r, ulong state1, ulong state2,
* @param fulong The function to fill an unsigned long.
* @param ptr The parameter to pass to @a fulong.
*/
-static void bc_rand_fill(BcRNGData *r, BcRandUlong fulong, void *ptr) {
-
+static void
+bc_rand_fill(BcRNGData* r, BcRandUlong fulong, void* ptr)
+{
ulong state1, state2, inc1, inc2;
state1 = fulong(ptr);
@@ -346,7 +367,9 @@ static void bc_rand_fill(BcRNGData *r, BcRandUlong fulong, void *ptr) {
* Executes the "step" portion of a PCG udpate.
* @param r The PRNG.
*/
-static void bc_rand_step(BcRNGData *r) {
+static void
+bc_rand_step(BcRNGData* r)
+{
BcRandState temp = bc_rand_mul2(r->state, bc_rand_multiplier);
r->state = bc_rand_add2(temp, bc_rand_inc(r));
}
@@ -356,7 +379,9 @@ static void bc_rand_step(BcRNGData *r) {
* @param r The PRNG.
* @return The new output from the PRNG.
*/
-static BcRand bc_rand_output(BcRNGData *r) {
+static BcRand
+bc_rand_output(BcRNGData* r)
+{
return BC_RAND_ROT(BC_RAND_FOLD(r->state), BC_RAND_ROTAMT(r->state));
}
@@ -366,9 +391,10 @@ static BcRand bc_rand_output(BcRNGData *r) {
* @param r The PRNG stack.
* @param rng The PRNG on the top of the stack. Must have been seeded.
*/
-static void bc_rand_seedZeroes(BcRNG *r, BcRNGData *rng, size_t idx) {
-
- BcRNGData *rng2;
+static void
+bc_rand_seedZeroes(BcRNG* r, BcRNGData* rng, size_t idx)
+{
+ BcRNGData* rng2;
// Just return if there are none to do.
if (r->v.len <= idx) return;
@@ -377,18 +403,21 @@ static void bc_rand_seedZeroes(BcRNG *r, BcRNGData *rng, size_t idx) {
rng2 = bc_vec_item_rev(&r->v, idx);
// Does it need seeding? Then it, and maybe more, do.
- if (BC_RAND_ZERO(rng2)) {
-
+ if (BC_RAND_ZERO(rng2))
+ {
size_t i;
// Seed the ones that need seeding.
for (i = 1; i < r->v.len; ++i)
+ {
bc_rand_copy(bc_vec_item_rev(&r->v, i), rng);
+ }
}
}
-void bc_rand_srand(BcRNGData *rng) {
-
+void
+bc_rand_srand(BcRNGData* rng)
+{
int fd = 0;
BC_SIG_LOCK;
@@ -398,16 +427,18 @@ void bc_rand_srand(BcRNGData *rng) {
// Try /dev/urandom first.
fd = open("/dev/urandom", O_RDONLY);
- if (BC_NO_ERR(fd >= 0)) {
+ if (BC_NO_ERR(fd >= 0))
+ {
bc_rand_fill(rng, bc_rand_frand, &fd);
close(fd);
}
- else {
-
+ else
+ {
// Try /dev/random second.
fd = open("/dev/random", O_RDONLY);
- if (BC_NO_ERR(fd >= 0)) {
+ if (BC_NO_ERR(fd >= 0))
+ {
bc_rand_fill(rng, bc_rand_frand, &fd);
close(fd);
}
@@ -418,7 +449,10 @@ void bc_rand_srand(BcRNGData *rng) {
#endif // _WIN32
// Fallback to rand() until the thing is seeded.
- while (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_fill(rng, bc_rand_rand, NULL);
+ while (BC_ERR(BC_RAND_ZERO(rng)))
+ {
+ bc_rand_fill(rng, bc_rand_rand, NULL);
+ }
BC_SIG_UNLOCK;
}
@@ -429,21 +463,22 @@ void bc_rand_srand(BcRNGData *rng) {
* @param r The PRNG stack.
* @param rng The PRNG that will be used to seed the others.
*/
-static void bc_rand_propagate(BcRNG *r, BcRNGData *rng) {
-
+static void
+bc_rand_propagate(BcRNG* r, BcRNGData* rng)
+{
// Just return if there are none to do.
if (r->v.len <= 1) return;
// If the PRNG has not been modified...
- if (BC_RAND_NOTMODIFIED(rng)) {
-
+ if (BC_RAND_NOTMODIFIED(rng))
+ {
size_t i;
bool go = true;
// Find the first PRNG that is modified and seed the others.
- for (i = 1; go && i < r->v.len; ++i) {
-
- BcRNGData *rng2 = bc_vec_item_rev(&r->v, i);
+ for (i = 1; go && i < r->v.len; ++i)
+ {
+ BcRNGData* rng2 = bc_vec_item_rev(&r->v, i);
go = BC_RAND_NOTMODIFIED(rng2);
@@ -457,10 +492,11 @@ static void bc_rand_propagate(BcRNG *r, BcRNGData *rng) {
else bc_rand_seedZeroes(r, rng, 1);
}
-BcRand bc_rand_int(BcRNG *r) {
-
+BcRand
+bc_rand_int(BcRNG* r)
+{
// Get the actual PRNG.
- BcRNGData *rng = bc_vec_top(&r->v);
+ BcRNGData* rng = bc_vec_top(&r->v);
BcRand res;
// Make sure the PRNG is seeded.
@@ -478,22 +514,29 @@ BcRand bc_rand_int(BcRNG *r) {
return res;
}
-BcRand bc_rand_bounded(BcRNG *r, BcRand bound) {
+BcRand
+bc_rand_bounded(BcRNG* r, BcRand bound)
+{
+ BcRand rand;
+ BcRand threshold;
// Calculate the threshold below which we have to try again.
- BcRand rand, threshold = (0 - bound) % bound;
+ threshold = (0 - bound) % bound;
- do {
+ do
+ {
rand = bc_rand_int(r);
- } while (rand < threshold);
+ }
+ while (rand < threshold);
return rand % bound;
}
-void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2)
+void
+bc_rand_seed(BcRNG* r, ulong state1, ulong state2, ulong inc1, ulong inc2)
{
// Get the actual PRNG.
- BcRNGData *rng = bc_vec_top(&r->v);
+ BcRNGData* rng = bc_vec_top(&r->v);
// Seed and set up the PRNG's increment.
bc_rand_seedState(&rng->inc, inc1, inc2);
@@ -502,7 +545,9 @@ void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2)
// If the state is 0, use the increment as the state. Otherwise, seed it
// with the state.
- if (!state1 && !state2) {
+ if (!state1 && !state2)
+ {
+ // NOLINTNEXTLINE
memcpy(&rng->state, &rng->inc, sizeof(BcRandState));
bc_rand_step(rng);
}
@@ -519,8 +564,9 @@ void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2)
* @return The increment without the odd bit and with being shifted one bit
* down.
*/
-static BcRandState bc_rand_getInc(BcRNGData *r) {
-
+static BcRandState
+bc_rand_getInc(BcRNGData* r)
+{
BcRandState res;
#if BC_RAND_BUILTIN
@@ -535,10 +581,11 @@ static BcRandState bc_rand_getInc(BcRNGData *r) {
return res;
}
-void bc_rand_getRands(BcRNG *r, BcRand *s1, BcRand *s2, BcRand *i1, BcRand *i2)
+void
+bc_rand_getRands(BcRNG* r, BcRand* s1, BcRand* s2, BcRand* i1, BcRand* i2)
{
BcRandState inc;
- BcRNGData *rng = bc_vec_top(&r->v);
+ BcRNGData* rng = bc_vec_top(&r->v);
if (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_srand(rng);
@@ -554,30 +601,38 @@ void bc_rand_getRands(BcRNG *r, BcRand *s1, BcRand *s2, BcRand *i1, BcRand *i2)
*i2 = BC_RAND_CHOP(inc);
}
-void bc_rand_push(BcRNG *r) {
-
- BcRNGData *rng = bc_vec_pushEmpty(&r->v);
+void
+bc_rand_push(BcRNG* r)
+{
+ BcRNGData* rng = bc_vec_pushEmpty(&r->v);
// Make sure the PRNG is properly zeroed because that marks it as needing to
// be seeded.
+ // NOLINTNEXTLINE
memset(rng, 0, sizeof(BcRNGData));
// If there is another item, copy it too.
if (r->v.len > 1) bc_rand_copy(rng, bc_vec_item_rev(&r->v, 1));
}
-void bc_rand_pop(BcRNG *r, bool reset) {
+void
+bc_rand_pop(BcRNG* r, bool reset)
+{
bc_vec_npop(&r->v, reset ? r->v.len - 1 : 1);
}
-void bc_rand_init(BcRNG *r) {
+void
+bc_rand_init(BcRNG* r)
+{
BC_SIG_ASSERT_LOCKED;
bc_vec_init(&r->v, sizeof(BcRNGData), BC_DTOR_NONE);
bc_rand_push(r);
}
#if BC_RAND_USE_FREE
-void bc_rand_free(BcRNG *r) {
+void
+bc_rand_free(BcRNG* r)
+{
BC_SIG_ASSERT_LOCKED;
bc_vec_free(&r->v);
}