128 lines
3.3 KiB
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;
|
|
}
|