#include // bool #define _DEFAULT_SOURCE #include // drand48_r() #include // fopen() #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 system random source (uses system rand()) 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; }