/* * mersenne.c -- component to provide random numbers on demand. */ #include #include #include #include #include "noisebox.h" enum { // assumes W = 32 N = 624, M = 397, R = 31, A = 0x9908B0DF, F = 1812433253, U = 11, // assumes D = 0xFFFFFFFF S = 7, B = 0x9D2C5680, T = 15, C = 0xEFC60000, L = 18, MASK_LOWER = (1ull << R) -1, MASK_UPPER = (1ull << R), }; // state for single generator. typedef struct mt_random_t { uint32_t mt[N]; int index; off_t begin; size_t consumed; char overflow[4]; int overflow_len; } mt_random_t; static void twist(mt_random_t *state) { uint32_t i, x, xA; uint32_t *mt = state->mt; for(i=0; i> 1; if(x & 0x1) xA ^= A; mt[i] = mt[(i+M) % N] ^ xA; } state->index = 0; } static void mt_init(mt_random_t *state, const uint32_t seed) { uint32_t i; uint32_t *mt = state->mt; mt[0] = seed; for(i=1; i> 30)) + i); } twist(state); } static uint32_t extract_u32(mt_random_t *state) { uint32_t y; if(state->index >= N) { twist(state); } int i = state->index; y = state->mt[i]; state->index++; y ^= (y >> U); y ^= (y << S) & B; y ^= (y << T) & C; y ^= (y >> L); return y; } static int do_open(const char *path, struct fuse_file_info *fi) { struct file_state *state = malloc(sizeof(struct file_state)); mt_random_t rng; mt_init(&rng, 0); fi->fh = (uint64_t)state; return 0; } static int do_getattr(const char *path, struct stat *st) { } static int get_noise(size_t n, off_t offset, char* buf, struct fuse_file_info *fi) { printf("getting random bits: %i@%i (%i)\n", n, offset, n*sizeof(char)); // FIXME this is wrong. mt_random_t *state = (mt_random_t *)(fi->fh); float buf_ratio = (float)sizeof(char)/(float)sizeof(uint32_t); if(offset != state->consumed * buf_ratio) { printf("wrong offset, discarding state\n"); } // TODO got distracted, never actually did this. uint32_t *tmp = malloc(n * sizeof(char)); printf("allocated %i\n", sizeof(char) * n); int count = n * buf_ratio; printf("calling extract_u32 %i times (%i * %f)\n", count, n, buf_ratio); for(int i=0; iconsumed, count); state->consumed += count; printf("wrote buf\n"); memcpy(buf, tmp, n); free(tmp); return n; } Noiser* mersenne_init(void) { Noiser* n = malloc(sizeof(Noiser)); n->name = "mersenne"; n->get_noise = get_noise; n->do_open = do_open; n->noisefile_count = 8; n->files = malloc(sizeof(NoiseFile *) * n->noisefile_count); n->files[0] = malloc(sizeof(NoiseFile)); n->files[0]->name = "1M"; n->files[0]->size = 1ULL<<20; n->files[1] = malloc(sizeof(NoiseFile)); n->files[1]->name = "1GiB"; n->files[1]->size = 1ULL<<30; n->files[2] = malloc(sizeof(NoiseFile)); n->files[2]->name = "100GiB"; n->files[2]->size = 100 * (1ULL<<30); n->files[3] = malloc(sizeof(NoiseFile)); n->files[3]->name = "200GiB"; n->files[3]->size = 200 * (1ULL<<30); n->files[4] = malloc(sizeof(NoiseFile)); n->files[4]->name = "400GiB"; n->files[4]->size = 400 * (1ULL<<30); n->files[5] = malloc(sizeof(NoiseFile)); n->files[5]->name = "1GB"; n->files[5]->size = 1000000000; n->files[6] = malloc(sizeof(NoiseFile)); n->files[6]->name = "100GB"; n->files[6]->size = 100000000000; n->files[7] = malloc(sizeof(NoiseFile)); n->files[7]->name = "200GB"; n->files[7]->size = 200000000000; return n; }