Exemplo n.º 1
0
store_t* open_mmap_store(const char* base_dir, const char* name, int flags) {
    int dir_fd = open(base_dir, O_DIRECTORY, (mode_t)0600);
    if (dir_fd == -1) return NULL;

    int real_fd = openat(dir_fd, name, O_RDWR, (mode_t)0600);
    ensure(real_fd > 0, "Failed to open mmap store file");
    close(dir_fd);

    struct stat sb;
    int ret = fstat(real_fd, &sb);
    ensure(ret != -1, "Failed to fstat file");
    int size = sb.st_size;

    // This is nearly identical to the create_mmap_store.  Maybe should make an "init mmap store" or
    // something?
    struct mmap_store *store = (struct mmap_store*) calloc(1, sizeof(struct mmap_store));
    if (store == NULL) return NULL;

    void *mapping = mmap(NULL, (size_t) size, PROT_READ | PROT_WRITE,
            MAP_SHARED | MAP_POPULATE | MAP_NONBLOCK , real_fd, 0);
    if (mapping == NULL) return NULL;

    madvise(mapping, size, MADV_SEQUENTIAL);

    uint32_t off = sizeof(uint32_t) * 2;
    ensure(((uint32_t *)mapping)[0] == 0xDEADBEEF, "Magic number does not match.  Bad file format");
    ensure(((uint32_t *)mapping)[1] == size, "Size recorded does not match file size.  Bad file format");

    ensure(asprintf(&(store->filename), "%s/%s", base_dir, name) > 0,
           "Failed to allocate store filename");

    store->fd = real_fd;
    store->capacity = size;
    store->flags = flags;
    store->mapping = mapping;

    // These don't really matter because writers aren't allowed...
    ck_pr_store_32(&store->write_cursor, off);
    ck_pr_store_32(&store->last_sync, 0);
    ck_pr_store_32(&store->read_cursor, -1);

    // We infer that this store has been synced...
    ck_pr_store_32(&store->syncing_and_writers, 0x80000000U);
    ck_pr_store_32(&store->synced, 1);
    ck_pr_fence_atomic();
    ensure(msync(mapping, off, MS_SYNC) == 0, "Unable to sync");
    ensure(store->write_cursor != 0, "Cursor incorrect");

    ((store_t *)store)->write        = &_mmap_write;
    ((store_t *)store)->open_cursor  = &_mmap_open_cursor;
    ((store_t *)store)->pop_cursor   = &_mmap_pop_cursor;
    ((store_t *)store)->capacity     = &_mmap_capacity;
    ((store_t *)store)->cursor       = &_mmap_cursor;
    ((store_t *)store)->start_cursor = &_mmap_start_cursor;
    ((store_t *)store)->sync         = &_mmap_sync;
    ((store_t *)store)->close        = &_mmap_close;
    ((store_t *)store)->destroy      = &_mmap_destroy;

    return (store_t *)store;
}
Exemplo n.º 2
0
store_t* create_mmap_store(uint32_t size, const char* base_dir, const char* name, int flags) {
    //TODO : Enforce a max size
    //TODO : Check flags
    //TODO : check thread sanity
    //TODO : check size is near a page
    int dir_fd = open(base_dir, O_DIRECTORY, (mode_t)0600);
    if (dir_fd == -1) return NULL;

    int real_fd = openat(dir_fd, name, O_RDWR | O_CREAT, (mode_t)0600);
    close(dir_fd);

    // TODO - Check for the race condition if two people attempt to create
    // the same segment
    if (real_fd == -1) return NULL;

    if (posix_fallocate(real_fd, 0, size) != 0) {
        close(real_fd);
        return NULL;
    }

    struct mmap_store *store = (struct mmap_store*) calloc(1, sizeof(struct mmap_store));
    if (store == NULL) return NULL;

    void *mapping = mmap(NULL, (size_t) size, PROT_READ | PROT_WRITE, 
            MAP_SHARED | MAP_POPULATE | MAP_NONBLOCK , real_fd, 0);
    if (mapping == NULL) return NULL;

    madvise(mapping, size, MADV_SEQUENTIAL);

    uint32_t off = sizeof(uint32_t) * 2;
    ((uint32_t *)mapping)[0] = 0xDEADBEEF;
    ((uint32_t *)mapping)[1] = size;

    store->fd = real_fd;
    store->capacity = size;
    store->flags = flags;
    store->mapping = mapping;

    ck_pr_store_32(&store->write_cursor, off);
    ck_pr_store_32(&store->sync_cursor, off);
    ck_pr_fence_atomic();
    ensure(msync(mapping, off, MS_SYNC) == 0, "Unable to sync");
    ensure(store->write_cursor != 0, "Cursor incorrect");
    ensure(store->sync_cursor != 0, "Cursor incorrect");

    ((store_t *)store)->write       = &_mmap_write;
    ((store_t *)store)->open_cursor = &_mmap_open_cursor;
    ((store_t *)store)->capacity    = &_mmap_capacity;
    ((store_t *)store)->cursor      = &_mmap_cursor;
    ((store_t *)store)->sync        = &_mmap_sync;
    ((store_t *)store)->close       = &_mmap_close;
    ((store_t *)store)->destroy     = &_mmap_destroy;

    return (store_t *)store;
}
Exemplo n.º 3
0
int
main(void)
{
	int r = 0;

	/* Below serves as a marker. */
	ck_pr_sub_int(&r, 31337);

	/*
	 * This is a simple test to help ensure all fences compile or crash
	 * on target. Below are generated according to the underlying memory
	 * model's ordering.
	 */
	ck_pr_fence_atomic();
	ck_pr_fence_atomic_store();
	ck_pr_fence_atomic_load();
	ck_pr_fence_store_atomic();
	ck_pr_fence_load_atomic();
	ck_pr_fence_load();
	ck_pr_fence_load_store();
	ck_pr_fence_store();
	ck_pr_fence_store_load();
	ck_pr_fence_memory();
	ck_pr_fence_release();
	ck_pr_fence_acquire();
	ck_pr_fence_acqrel();
	ck_pr_fence_lock();
	ck_pr_fence_unlock();

	/* Below serves as a marker. */
	ck_pr_sub_int(&r, 31337);

	/* The following are generating assuming RMO. */
	ck_pr_fence_strict_atomic();
	ck_pr_fence_strict_atomic_store();
	ck_pr_fence_strict_atomic_load();
	ck_pr_fence_strict_store_atomic();
	ck_pr_fence_strict_load_atomic();
	ck_pr_fence_strict_load();
	ck_pr_fence_strict_load_store();
	ck_pr_fence_strict_store();
	ck_pr_fence_strict_store_load();
	ck_pr_fence_strict_memory();
	ck_pr_fence_strict_release();
	ck_pr_fence_strict_acquire();
	ck_pr_fence_strict_acqrel();
	ck_pr_fence_strict_lock();
	ck_pr_fence_strict_unlock();
	return 0;
}
Exemplo n.º 4
0
store_t* create_mmap_store(uint32_t size, const char* base_dir, const char* name, int flags) {
    //TODO : Enforce a max size
    //TODO : Check flags
    //TODO : check thread sanity
    //TODO : check size is near a page
    int dir_fd = open(base_dir, O_DIRECTORY, (mode_t)0600);
    if (dir_fd == -1) return NULL;

    int openat_flags = O_RDWR | O_CREAT | O_SYNC;

    if (flags & DELETE_IF_EXISTS) {
        openat_flags = openat_flags | O_TRUNC;
    }
    else {
        openat_flags = openat_flags | O_EXCL;
    }

    int real_fd = openat(dir_fd, name, openat_flags, (mode_t)0600);
    close(dir_fd);

    // TODO - Check for the race condition if two people attempt to create
    // the same segment
    if (real_fd == -1) {
        // TODO: This is a terrible hack.  We need to fix the error handling, but for now, actually
        // warn us if we are failing because of loading a garbage file.
        ensure(errno != EEXIST, "Failed to create mmap store because file already exists");
        return NULL;
    }

    if (posix_fallocate(real_fd, 0, size) != 0) {
        close(real_fd);
        return NULL;
    }

    struct mmap_store *store = (struct mmap_store*) calloc(1, sizeof(struct mmap_store));
    if (store == NULL) return NULL;

    void *mapping = mmap(NULL, (size_t) size, PROT_READ | PROT_WRITE, 
            MAP_SHARED | MAP_POPULATE | MAP_NONBLOCK , real_fd, 0);
    if (mapping == NULL) return NULL;

    madvise(mapping, size, MADV_SEQUENTIAL);

    uint32_t off = sizeof(uint32_t) * 2;
    ((uint32_t *)mapping)[0] = 0xDEADBEEF;
    ((uint32_t *)mapping)[1] = size;

    ensure(asprintf(&(store->filename), "%s/%s", base_dir, name) > 0,
           "Failed to allocate store filename");

    store->fd = real_fd;
    store->capacity = size;
    store->flags = flags;
    store->mapping = mapping;

    ck_pr_store_32(&store->write_cursor, off);
    ck_pr_store_32(&store->last_sync, 0);
    ck_pr_store_32(&store->read_cursor, -1);
    ck_pr_store_32(&store->syncing_and_writers, 0);
    ck_pr_store_32(&store->synced, 0);
    ck_pr_fence_atomic();
    ensure(msync(mapping, off, MS_SYNC) == 0, "Unable to sync");
    ensure(store->write_cursor != 0, "Cursor incorrect");

    ((store_t *)store)->write        = &_mmap_write;
    ((store_t *)store)->open_cursor  = &_mmap_open_cursor;
    ((store_t *)store)->pop_cursor   = &_mmap_pop_cursor;
    ((store_t *)store)->capacity     = &_mmap_capacity;
    ((store_t *)store)->cursor       = &_mmap_cursor;
    ((store_t *)store)->start_cursor = &_mmap_start_cursor;
    ((store_t *)store)->sync         = &_mmap_sync;
    ((store_t *)store)->close        = &_mmap_close;
    ((store_t *)store)->destroy      = &_mmap_destroy;

    return (store_t *)store;
}