/* * pcg.c -- component to provide random numbers from pcg on demand. */ #include #include #include #include #include "noisebox.h" // static int do_readdir(const char *path, void *buffer, // fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { // filler(buffer, ".", NULL, 0); // filler(buffer, "..", NULL, 0); // } static int do_getattr(const char *path, struct stat *st) { return 0; } static int get_state(const char *path, struct fuse_file_info *fi) { return 0; } static int do_open(const char *path, struct fuse_file_info *fi) { // only called if state isn't already inited. struct file_state *state = malloc(sizeof(struct file_state)); pcg32_random_t p; // fixed constant seed pcg32_srandom_r(&p, 42u, 54u); state->rng.pcg = &p; state->next = NULL; state->char_ratio = 4; state->consumed = 0; fi->fh = (uint64_t)state; return 0; } static int do_release(const char *path, struct fuse_file_info *fi) { free((void *)(fi->fh)); return 0; } static int get_noise(size_t n, off_t offset, char* buf, struct fuse_file_info *fi) { printf("getting pcg rand: %i:%i\n", n, offset); printf("sizeof buf = %zu (%zu * %i)\n", n * sizeof(char), n, sizeof(char)); struct file_state *fh = (struct file_state *)(fi->fh); pcg32_random_t *rng = fh->rng.pcg; // if offset doesn't match, seek. if(fh->consumed != offset) { pcg32_advance_r(rng, offset - fh->consumed); fh->consumed = offset; } uint32_t *tmp = malloc(n); for(int i=0; (i*fh->char_ratio)consumed += n; memcpy(buf, tmp, n); free(tmp); printf("pcg random numbers obtained\n"); return n; } Noiser* pcg_init(void) { Noiser* n = malloc(sizeof(Noiser)); n->name = "pcg"; n->state = NULL; n->get_noise = get_noise; n->do_open = do_open; n->do_release = do_release; // manually keep track of file count for now. n->noisefile_count = 10; 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 = "1G"; n->files[1]->size = 1ULL<<30; n->files[2] = malloc(sizeof(NoiseFile)); n->files[2]->name = "100G"; 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; n->files[8] = malloc(sizeof(NoiseFile)); n->files[8]->name = "400GB"; n->files[8]->size = 400000000000; n->files[9] = malloc(sizeof(NoiseFile)); n->files[9]->name = "800GB"; n->files[9]->size = 800000000000; return n; }