-
Notifications
You must be signed in to change notification settings - Fork 0
/
rng.cc
76 lines (62 loc) · 1.5 KB
/
rng.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#pragma once
namespace KERF_NAMESPACE
{
#pragma mark -
void RNG::dev_urandom_bits_fill(void* buf, size_t buflen)
{
// POP when we don't need to read from device, we can read from our seeded pseudorandom generator instead
I f=open("/dev/urandom",0);
I r=read(f,buf,buflen);
if(!r)
{
kerf_exit(EX_OSERR);
}
close(f);
}
I RNG::dev_urandom_bits_64()
{
I s;
dev_urandom_bits_fill(&s,sizeof(s));
return s;
}
I4 RNG::dev_urandom_bits_128()
{
I4 s;
dev_urandom_bits_fill(&s,sizeof(s));
return s;
}
void RNG::seed_randomized()
{
pcg.seed(dev_urandom_bits_128(), dev_urandom_bits_128());
}
void RNG::seed_fixed(I seed)
{
pcg.seed(std::seed_seq{seed, seed});
}
void RNG::seed_fixed_all_rng(I seed)
{
DO(KERF_MAX_NORMALIZABLE_THREAD_COUNT, The_Thread_RNGs[i].seed_fixed(seed + i))
}
RNG::RNG()
{
if(RNG_USES_RANDOMIZED_SEED_ON_INIT && !DEBUG)
{
seed_randomized();
}
else
{
auto i = global_counter++; // seed thread instances in order, simply but differently
seed_fixed(i);
}
}
auto RNG::get_my_rng()
{
// Remark. Even if you made a global threadsafe singleton that returned
// pseudo-random values, you wouldn't get reproducible results because the
// threads would contend for it in unreproducible order. If you could control
// the thread timings (there may be a way to do this but I don't know it
// currently 2021.07.21) then you could guarantee reproducible multithreaded
// randomness.
return The_Thread_RNGs[kerf_get_cached_normalized_thread_id()];
}
}