Skip to content

Instantly share code, notes, and snippets.

@fritschy
Last active November 20, 2015 14:10
Show Gist options
  • Save fritschy/902913a2971b7dfca9ad to your computer and use it in GitHub Desktop.
Save fritschy/902913a2971b7dfca9ad to your computer and use it in GitHub Desktop.
Quickly generate a stream of random data
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>
// see https://github.com/imneme/pcg-c
#include "pcg_variants.h"
// INEXACT output; if we are interrupted the buffer if not flushed.
static char out_buf[2][1024*1024];
static int out_cur = 0;
static volatile int wbuf = 0;
pthread_barrier_t barrier;
static void *writer(void *x) {
(void) x;
while (1) {
pthread_barrier_wait(&barrier); // wait 1, sync for buffer ready
pthread_barrier_wait(&barrier); // wait 2, wbuf is being updated
write(STDOUT_FILENO, out_buf[wbuf^1], sizeof(out_buf[0]));
}
return NULL;
}
static inline void out8(void *b) {
if (__builtin_expect(out_cur == sizeof(out_buf[0]), 0)) {
pthread_barrier_wait(&barrier); // wait 1
wbuf ^= 1;
out_cur = 0;
pthread_barrier_wait(&barrier); // wait 2
}
memcpy(out_buf[wbuf]+out_cur, b, 8);
out_cur += 8;
}
int main(int argc, char **argv) {
(void) argc;
pthread_t th;
pthread_barrier_init(&barrier, NULL, 2);
pthread_create(&th, NULL, writer, NULL);
pthread_detach(th);
char *end = NULL;
uint64_t seed = 0x853c49e6748fea9bULL;
if (argv[1]) {
seed = strtoull(argv[1], &end, 10);
if (end)
seed = 0x853c49e6748fea9bULL;
}
pcg64_random_t r[1];
pcg64_srandom_r(r, seed, 1);
while (1) {
uint64_t i = pcg64_random_r(r);
out8(&i);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment