Created
November 10, 2017 15:18
-
-
Save sw17ch/faab148276ded76e78d93fc939238ce1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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