Skip to content

Instantly share code, notes, and snippets.

@sw17ch
Created November 10, 2017 15:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sw17ch/faab148276ded76e78d93fc939238ce1 to your computer and use it in GitHub Desktop.
Save sw17ch/faab148276ded76e78d93fc939238ce1 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>
#define MMAP_PATH "toy.mmap"
#define COLUMN_SIZE (16)
#define NAME_SIZE (64)
#define ALEN(A) (sizeof(A) / sizeof(A[0]))
struct record {
uint64_t id;
int64_t value;
};
struct columns {
char name[NAME_SIZE];
uint64_t next_id;
struct record records[COLUMN_SIZE];
};
static uint64_t get_timestamp(void);
static struct columns * map_columns(char const * path);
static void unmap_columns(struct columns * map);
static void record(struct columns * cols, int32_t value);
int main(int argc, char * argv[])
{
(void)argc;
(void)argv;
struct columns * cols = map_columns(MMAP_PATH);
for (int i = 1; i < argc; i++) {
record(cols, atoi(argv[i]));
}
unmap_columns(cols);
return 0;
}
static uint64_t get_timestamp(void)
{
struct timespec ts;
if (0 > clock_gettime(CLOCK_REALTIME, &ts)) {
err(1, "failed to get time");
}
uint64_t ns = ts.tv_sec * (1000 * 1000 * 1000);
ns += ts.tv_nsec;
return ns;
}
static struct columns * map_columns(char const * path)
{
size_t const SIZE = sizeof(struct columns);
mode_t const OMODE =
S_IRUSR | S_IWUSR |
S_IRGRP |
S_IROTH;
int const OFLAGS = O_RDWR | O_CREAT;
int fd = -1;
if ((fd = open(path, OFLAGS, OMODE)) < 0) {
err(2, "could not open %s", path);
}
if (0 > lseek(fd, SIZE, SEEK_SET)) {
err(2, "could not seek");
}
uint64_t const ts = get_timestamp();
if (0 > write(fd, &ts, sizeof(uint64_t))) {
err(2, "could not write");
}
int const MPROT = PROT_READ | PROT_WRITE;
int const MFLAGS = MAP_FILE | MAP_SHARED;
void * mmap_ptr = mmap(NULL, SIZE, MPROT, MFLAGS, fd, 0);
if (MAP_FAILED == mmap_ptr) {
err(2, "could not map memory");
}
if (0 > close(fd)) {
err(2, "could not close file");
}
struct columns * cols = mmap_ptr;
strncpy(cols->name, path, sizeof(cols->name));
return cols;
}
static void unmap_columns(struct columns * map)
{
if (0 > munmap((void *)map, sizeof(*map))) {
err(3, "could not unmap memory");
}
}
static void record(struct columns * cols, int32_t value)
{
/* This would need locking/coordination with other
* threads/procs that may also interact with the mmap'ed
* file. */
size_t const ix = cols->next_id % ALEN(cols->records);
cols->records[ix].id = cols->next_id;
cols->records[ix].value = value;
cols->next_id += 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment