blob: 3d7b02d8296a801e1b818944b9deff704abda47f (
plain)
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include <stdbool.h> // bool
#define _DEFAULT_SOURCE
#include <stdlib.h> // erand48()
#include "util.h"
#include "km.h"
// get N get_floats
static bool
on_get_floats(
km_rand_t * const rs,
const size_t num_vals,
float * const vals
) {
unsigned short * const data = rs->data;
// generate results
for (size_t i = 0; i < num_vals; i++) {
vals[i] = erand48(data);
}
// return success
return true;
}
// fill sizes callback for system random source
static bool
on_get_sizes(
km_rand_t * const rs,
const size_t num_vals,
size_t * const vals
) {
unsigned short * const data = rs->data;
// generate results
for (size_t i = 0; i < num_vals; i++) {
vals[i] = nrand48(data);
}
// return success
return true;
}
static void
on_fini(
km_rand_t * const rs
) {
unsigned short * data = rs->data;
// free rng data
free(data);
// clear pointer
rs->data = NULL;
}
// path random source callbacks
static const km_rand_cbs_t
ERAND48_RAND_CBS = {
.get_floats = on_get_floats,
.get_sizes = on_get_sizes,
.fini = on_fini,
};
// init erand48 random source (uses erand48(), seeded with the lower
// 48-bits of the seed parameter)
bool
km_rand_init_erand48(
km_rand_t * const rs,
const uint64_t seed
) {
// alloc rng data
unsigned short * const data = malloc(3 * sizeof(unsigned short));
if (!data) {
// return failure
return false;
}
// populate seed
data[0] = seed & 0xffff;
data[1] = (seed >> 16) & 0xffff;
data[2] = (seed >> 32) & 0xffff;
// populate context
rs->cbs = &ERAND48_RAND_CBS;
rs->data = data;
// return success
return true;
}
|