noisebox/pcg.c

128 lines
3.3 KiB
C

/*
* pcg.c -- component to provide random numbers from pcg on demand.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcg_variants.h>
#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;
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)<n; i++) {
tmp[i] = pcg32_random_r(rng);
// printf("got some noise, %i of %i\n", i, n);
}
fh->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;
}