Commit | Line | Data |
---|---|---|
1fbbf72e JA |
1 | #ifndef FIO_RAND_H |
2 | #define FIO_RAND_H | |
3 | ||
c3546b53 | 4 | #include <inttypes.h> |
16dc0710 JA |
5 | #include "../arch/arch.h" |
6 | ||
c3546b53 JA |
7 | #define FRAND32_MAX (-1U) |
8 | #define FRAND64_MAX (-1ULL) | |
2615cc4b | 9 | |
c3546b53 | 10 | struct taus88_state { |
1fbbf72e JA |
11 | unsigned int s1, s2, s3; |
12 | }; | |
13 | ||
c3546b53 JA |
14 | struct taus258_state { |
15 | uint64_t s1, s2, s3, s4, s5; | |
16 | }; | |
17 | ||
18 | struct frand_state { | |
19 | unsigned int use64; | |
20 | union { | |
21 | struct taus88_state state32; | |
22 | struct taus258_state state64; | |
23 | }; | |
24 | }; | |
25 | ||
26 | struct frand64_state { | |
27 | uint64_t s1, s2, s3, s4, s5; | |
28 | }; | |
29 | ||
30 | static inline uint64_t rand_max(struct frand_state *state) | |
31 | { | |
32 | if (state->use64) | |
33 | return FRAND64_MAX; | |
34 | else | |
35 | return FRAND32_MAX; | |
36 | } | |
37 | ||
38 | static inline void __frand32_copy(struct taus88_state *dst, | |
39 | struct taus88_state *src) | |
40 | { | |
41 | dst->s1 = src->s1; | |
42 | dst->s2 = src->s2; | |
43 | dst->s3 = src->s3; | |
44 | } | |
45 | ||
46 | static inline void __frand64_copy(struct taus258_state *dst, | |
47 | struct taus258_state *src) | |
5c94b008 JA |
48 | { |
49 | dst->s1 = src->s1; | |
50 | dst->s2 = src->s2; | |
51 | dst->s3 = src->s3; | |
c3546b53 JA |
52 | dst->s4 = src->s4; |
53 | dst->s5 = src->s5; | |
5c94b008 JA |
54 | } |
55 | ||
c3546b53 JA |
56 | static inline void frand_copy(struct frand_state *dst, struct frand_state *src) |
57 | { | |
58 | if (src->use64) | |
59 | __frand64_copy(&dst->state64, &src->state64); | |
60 | else | |
61 | __frand32_copy(&dst->state32, &src->state32); | |
62 | ||
63 | dst->use64 = src->use64; | |
64 | } | |
65 | ||
66 | static inline unsigned int __rand32(struct taus88_state *state) | |
1fbbf72e JA |
67 | { |
68 | #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) | |
69 | ||
70 | state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12); | |
71 | state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4); | |
72 | state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17); | |
73 | ||
74 | return (state->s1 ^ state->s2 ^ state->s3); | |
75 | } | |
76 | ||
c3546b53 JA |
77 | static inline uint64_t __rand64(struct taus258_state *state) |
78 | { | |
79 | uint64_t xval; | |
80 | ||
81 | xval = ((state->s1 << 1) ^ state->s1) >> 53; | |
82 | state->s1 = ((state->s1 & 18446744073709551614ULL) << 10) ^ xval; | |
83 | ||
84 | xval = ((state->s2 << 24) ^ state->s2) >> 50; | |
85 | state->s2 = ((state->s2 & 18446744073709551104ULL) << 5) ^ xval; | |
86 | ||
87 | xval = ((state->s3 << 3) ^ state->s3) >> 23; | |
88 | state->s3 = ((state->s3 & 18446744073709547520ULL) << 29) ^ xval; | |
89 | ||
90 | xval = ((state->s4 << 5) ^ state->s4) >> 24; | |
91 | state->s4 = ((state->s4 & 18446744073709420544ULL) << 23) ^ xval; | |
92 | ||
93 | xval = ((state->s5 << 3) ^ state->s5) >> 33; | |
94 | state->s5 = ((state->s5 & 18446744073701163008ULL) << 8) ^ xval; | |
95 | ||
96 | return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4 ^ state->s5); | |
97 | } | |
98 | ||
99 | static inline uint64_t __rand(struct frand_state *state) | |
100 | { | |
101 | if (state->use64) | |
102 | return __rand64(&state->state64); | |
103 | else | |
104 | return __rand32(&state->state32); | |
105 | } | |
106 | ||
e7b24047 JA |
107 | static inline double __rand_0_1(struct frand_state *state) |
108 | { | |
109 | if (state->use64) { | |
110 | uint64_t val = __rand64(&state->state64); | |
111 | ||
592bf458 | 112 | return (val + 1.0) / (FRAND64_MAX + 1.0); |
e7b24047 JA |
113 | } else { |
114 | uint32_t val = __rand32(&state->state32); | |
115 | ||
592bf458 | 116 | return (val + 1.0) / (FRAND32_MAX + 1.0); |
e7b24047 JA |
117 | } |
118 | } | |
119 | ||
c3546b53 JA |
120 | extern void init_rand(struct frand_state *, int); |
121 | extern void init_rand_seed(struct frand_state *, unsigned int seed, int); | |
7d9fb455 | 122 | extern void __fill_random_buf(void *buf, unsigned int len, unsigned long seed); |
3545a109 | 123 | extern unsigned long fill_random_buf(struct frand_state *, void *buf, unsigned int len); |
bc769898 | 124 | extern void __fill_random_buf_percentage(unsigned long, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int); |
d1af2894 | 125 | extern unsigned long fill_random_buf_percentage(struct frand_state *, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int); |
1fbbf72e JA |
126 | |
127 | #endif |