typedef struct {
// This shouldn't really be here but I'm too lazy to make another struct
// It's for signaling the generators that they should stop generating
int please_exit;
char offset_read;
char offset_write;
sem_t sem_read;
sem_t sem_write;
sem_t sem_lock;
size_t size;
size_t free_space;
size_t used_space;
char data[];
} circular_buffer;
circular_buffer* make_circular_buffer(size_t size, char* file){
char protection = PROT_READ | PROT_WRITE;
char visibility;
int fd;
if(file == NULL){
visibility = MAP_ANONYMOUS | MAP_SHARED;
fd = 0;
} else {
visibility = MAP_SHARED;
fd = open(file, O_CREAT | O_RDWR);
ftruncate(fd, sizeof(circular_buffer) + size);
if(fd < 0){
fprintf(stderr, "make_circular_buffer: opening file failed.\n");
exit(10);
}
}
circular_buffer* b = mmap(
NULL,
sizeof(circular_buffer) + size,
protection, visibility, fd, 0
);
if(b == MAP_FAILED) {
fprintf(stderr, "make_circular_buffer: mmap error.\n");
exit(11);
}
if(file != NULL){
close(fd);
}
b->please_exit = 0;
b->offset_read = 0;
b->offset_write = 0;
b->size = size;
b->data = (char*)(b) + sizeof(circular_buffer);
b->free_space = size;
b->used_space = 0;
return b;
}