static void pool_create(const char *path, const char *layout, size_t poolsize, unsigned mode) { PMEMobjpool *pop = pmemobj_create(path, layout, poolsize, mode); if (pop == NULL) UT_OUT("!%s: pmemobj_create", path); else { struct stat stbuf; STAT(path, &stbuf); UT_OUT("%s: file size %zu mode 0%o", path, stbuf.st_size, stbuf.st_mode & 0777); pmemobj_close(pop); int result = pmemobj_check(path, layout); if (result < 0) UT_OUT("!%s: pmemobj_check", path); else if (result == 0) UT_OUT("%s: pmemobj_check: not consistent", path); } }
int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_mt"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); if ((pop = pmemobj_create(argv[1], "mt", PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create"); int i = 0; long ncpus = sysconf(_SC_NPROCESSORS_ONLN); pthread_t *threads = MALLOC(2 * ncpus * sizeof(threads[0])); for (int j = 0; j < ncpus; ++j) { PTHREAD_CREATE(&threads[i++], NULL, tx_alloc_free, NULL); PTHREAD_CREATE(&threads[i++], NULL, tx_snap, NULL); } while (i > 0) PTHREAD_JOIN(threads[--i], NULL); pmemobj_close(pop); FREE(threads); DONE(NULL); }
static void test_reopen(const char *path) { PMEMobjpool *pop1 = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (!pop1) UT_FATAL("!create"); PMEMobjpool *pop2 = pmemobj_open(path, LAYOUT); if (pop2) UT_FATAL("pmemobj_open should not succeed"); if (errno != EWOULDBLOCK) UT_FATAL("!pmemobj_open failed but for unexpected reason"); pmemobj_close(pop1); pop2 = pmemobj_open(path, LAYOUT); if (!pop2) UT_FATAL("pmemobj_open should succeed after close"); pmemobj_close(pop2); UNLINK(path); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_pmalloc_oom_mt"); if (argc != 2) FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) FATAL("!pmemobj_create: %s", path); pthread_t t; pthread_create(&t, NULL, oom_worker, NULL); pthread_join(t, NULL); int first_thread_allocated = allocated; pthread_create(&t, NULL, oom_worker, NULL); pthread_join(t, NULL); ASSERTeq(first_thread_allocated, allocated); pmemobj_close(pop); DONE(NULL); }
static void test_open_in_different_process(int argc, char **argv, int sleep) { PMEMobjpool *pop; if (sleep > 0) return; char *path = argv[1]; /* before starting the 2nd process, create a pool */ pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (!pop) UT_FATAL("!create"); /* * "X" is pass as an additional param to the new process * created by ut_spawnv to distinguish second process on Windows */ uintptr_t result = ut_spawnv(argc, argv, "X", NULL); if (result == -1) UT_FATAL("Create new process failed error: %d", GetLastError()); pmemobj_close(pop); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_heap_state"); if (argc != 2) FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) FATAL("!pmemobj_create: %s", path); pmemobj_root(pop, ROOT_SIZE); /* just to trigger allocation */ pmemobj_close(pop); pop = pmemobj_open(path, LAYOUT_NAME); ASSERTne(pop, NULL); for (int i = 0; i < ALLOCS; ++i) { PMEMoid oid; pmemobj_alloc(pop, &oid, ALLOC_SIZE, 0, NULL, NULL); OUT("%d %lu", i, oid.off); } pmemobj_close(pop); DONE(NULL); }
/* * pmemlog_create -- pool create wrapper */ PMEMlogpool * pmemlog_create(const char *path, size_t poolsize, mode_t mode) { return (PMEMlogpool *)pmemobj_create(path, POBJ_LAYOUT_NAME(obj_pmemlog_minimal), poolsize, mode); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_out_of_memory"); if (argc < 3) FATAL("usage: %s size filename ...", argv[0]); size_t size = atoll(argv[1]); for (int i = 2; i < argc; i++) { const char *path = argv[i]; PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR); if (pop == NULL) FATAL("!pmemobj_create: %s", path); test_alloc(pop, size); pmemobj_close(pop); ASSERTeq(pmemobj_check(path, LAYOUT_NAME), 1); ASSERTne(pop = pmemobj_open(path, LAYOUT_NAME), NULL); test_free(pop); pmemobj_close(pop); } DONE(NULL); }
int main(int argc, char *argv[]) { if (argc != 2) { printf("usage: %s file-name\n", argv[0]); return 1; } PMEMobjpool *pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, 0666); if (pop == NULL) { perror("pmemobj_create"); return 1; } PMEMoid root = pmemobj_root(pop, sizeof(struct my_root)); struct my_root *rootp = pmemobj_direct(root); char buf[MAX_BUF_LEN]; if (scanf("%9s", buf) == EOF) { fprintf(stderr, "EOF\n"); return 1; } rootp->len = strlen(buf); pmemobj_persist(pop, &rootp->len, sizeof(rootp->len)); pmemobj_memcpy_persist(pop, rootp->buf, buf, rootp->len); pmemobj_close(pop); return 0; }
int main(int argc, char *argv[]) { if (argc < 3 || argc > 4) { printf("usage: %s hashmap_tx|hashmap_atomic|ctree|btree|rbtree" " file-name [<seed>]\n", argv[0]); return 1; } const struct map_ops *ops = NULL; const char *path = argv[2]; const char *type = argv[1]; if (strcmp(type, "hashmap_tx") == 0) { ops = MAP_HASHMAP_TX; } else if (strcmp(type, "hashmap_atomic") == 0) { ops = MAP_HASHMAP_ATOMIC; } else if (strcmp(type, "ctree") == 0) { ops = MAP_CTREE; } else if (strcmp(type, "btree") == 0) { ops = MAP_BTREE; } else if (strcmp(type, "rbtree") == 0) { ops = MAP_RBTREE; } else { fprintf(stderr, "invalid hasmap type -- '%s'\n", type); return 1; } if (access(path, F_OK) != 0) { pop = pmemobj_create(path, POBJ_LAYOUT_NAME(map), PM_HASHSET_POOL_SIZE, S_IRUSR | S_IWUSR); if (pop == NULL) { fprintf(stderr, "failed to create pool: %s\n", pmemobj_errormsg()); return 1; } struct hashmap_args args; if (argc > 3) args.seed = atoi(argv[3]); else args.seed = time(NULL); srand(args.seed); mapc = map_ctx_init(ops, pop); if (!mapc) { pmemobj_close(pop); perror("map_ctx_init"); return 1; } root = POBJ_ROOT(pop, struct root); printf("seed: %u\n", args.seed); map_new(mapc, &D_RW(root)->map, &args); map = D_RO(root)->map; } else {
int art_tree_map_init(struct datastore *ds, struct ds_context *ctx) { int errors = 0; char *error_string; /* calculate a required pool size */ if (ctx->psize < PMEMOBJ_MIN_POOL) ctx->psize = PMEMOBJ_MIN_POOL; if (!ctx->fileio) { if (access(ctx->filename, F_OK) != 0) { error_string = "pmemobj_create"; ctx->pop = pmemobj_create(ctx->filename, POBJ_LAYOUT_NAME(arttree_tx), ctx->psize, ctx->fmode); ctx->newpool = 1; } else { error_string = "pmemobj_open"; ctx->pop = pmemobj_open(ctx->filename, POBJ_LAYOUT_NAME(arttree_tx)); } if (ctx->pop == NULL) { perror(error_string); errors++; } } else { int flags = O_CREAT | O_RDWR | O_SYNC; /* Create a file if it does not exist. */ if ((ctx->fd = open(ctx->filename, flags, ctx->fmode)) < 0) { perror(ctx->filename); errors++; } /* allocate the pmem */ if ((errno = posix_fallocate(ctx->fd, 0, ctx->psize)) != 0) { perror("posix_fallocate"); errors++; } } if (!errors) { pmemobj_ds_set_priv(ds, ctx); } else { if (ctx->fileio) { if (ctx->fd >= 0) { close(ctx->fd); } } else { if (ctx->pop) { pmemobj_close(ctx->pop); } } } return errors; }
int main(int argc, char *argv[]) { START(argc, argv, "obj_direct"); if (argc != 3) FATAL("usage: %s [directory] [# of pools]", argv[0]); int npools = atoi(argv[2]); const char *dir = argv[1]; int r; PMEMobjpool *pops[npools]; char path[MAX_PATH_LEN]; for (int i = 0; i < npools; ++i) { snprintf(path, MAX_PATH_LEN, "%s/testfile%d", dir, i); pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (pops[i] == NULL) FATAL("!pmemobj_create"); } PMEMoid oids[npools]; PMEMoid tmpoids[npools]; oids[0] = OID_NULL; ASSERTeq(pmemobj_direct(oids[0]), NULL); for (int i = 0; i < npools; ++i) { oids[i] = (PMEMoid) {pops[i]->uuid_lo, 0}; ASSERTeq(pmemobj_direct(oids[i]), NULL); uint64_t off = pops[i]->heap_offset; oids[i] = (PMEMoid) {pops[i]->uuid_lo, off}; ASSERTeq(pmemobj_direct(oids[i]) - off, pops[i]); r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL); ASSERTeq(r, 0); } for (int i = 0; i < npools; ++i) { ASSERTne(pmemobj_direct(tmpoids[i]), NULL); pmemobj_free(&tmpoids[i]); ASSERTeq(pmemobj_direct(tmpoids[i]), NULL); pmemobj_close(pops[i]); ASSERTeq(pmemobj_direct(oids[i]), NULL); } DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_fragmentation2"); if (argc < 3) UT_FATAL("usage: %s filename workload [seed]", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, DEFAULT_FILE_SIZE, S_IWUSR | S_IRUSR); if (pop == NULL) UT_FATAL("!pmemobj_create: %s", path); int w = atoi(argv[2]); if (argc > 3) seed = (unsigned)atoi(argv[3]); else seed = time(NULL); objects = ZALLOC(sizeof(uint64_t) * MAX_OBJECTS); UT_ASSERTne(objects, NULL); workloads[w - 1](pop); PMEMoid oid; size_t remaining = 0; size_t chunk = 100; /* calc at chunk level */ while (pmemobj_alloc(pop, &oid, chunk, 0, NULL, NULL) == 0) remaining += pmemobj_alloc_usable_size(oid) + 16; size_t allocated_sum = 0; oid = pmemobj_root(pop, 1); for (size_t n = 0; n < nobjects; ++n) { if (objects[n] == 0) continue; oid.off = objects[n]; allocated_sum += pmemobj_alloc_usable_size(oid) + 16; } size_t used = DEFAULT_FILE_SIZE - remaining; float frag = ((float)used / allocated_sum) - 1.f; UT_ASSERT(frag <= workloads_target[w - 1]); pmemobj_close(pop); FREE(objects); DONE(NULL); }
static void test_fault_injection(const char *path, const char *layout, size_t poolsize, unsigned mode) { if (!pmemobj_fault_injection_enabled()) return; pmemobj_inject_fault_at(PMEM_MALLOC, 1, "tx_params_new"); PMEMobjpool *pop = pmemobj_create(path, layout, poolsize, mode); UT_ASSERTeq(pop, NULL); UT_ASSERTeq(errno, ENOMEM); }
/** * Creates a new transactional object store pool. * * @param path System path to the file to be created. If exists * the pool can be created in-place depending on the size * parameter. Existing file must be zeroed. * @param layout Unique identifier of the pool, can be a * NULL-terminated string. * @param size Size of the pool in bytes. If zero and the file * exists the pool is created in-place. * @param mode File mode for the new file. * * @return handle to the created pool. * * @throw nvml::pool_error when an error during creation occurs. */ static pool_base create(const std::string &path, const std::string &layout, std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = S_IWUSR | S_IRUSR) { pmemobjpool *pop = pmemobj_create(path.c_str(), layout.c_str(), size, mode); if (pop == nullptr) throw pool_error("Failed creating pool"); return pool_base(pop); }
static void test_open_in_different_process(int argc, char **argv, int sleep) { pid_t pid = fork(); PMEMobjpool *pop; char *path = argv[1]; if (pid < 0) UT_FATAL("fork failed"); if (pid == 0) { /* child */ if (sleep) usleep(sleep); while (os_access(path, R_OK)) usleep(100 * 1000); pop = pmemobj_open(path, LAYOUT); if (pop) UT_FATAL("pmemobj_open after fork should not succeed"); if (errno != EWOULDBLOCK) UT_FATAL("!pmemobj_open after fork failed but for " "unexpected reason"); exit(0); } pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (!pop) UT_FATAL("!create"); int status; if (waitpid(pid, &status, 0) < 0) UT_FATAL("!waitpid failed"); if (!WIFEXITED(status)) UT_FATAL("child process failed"); pmemobj_close(pop); UNLINK(path); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_out_of_memory"); if (argc < 3) FATAL("usage: %s size filename ...", argv[0]); size_t size = atoll(argv[1]); for (int i = 2; i < argc; i++) { const char *path = argv[i]; PMEMobjpool *pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR); if (pop == NULL) FATAL("!pmemobj_create: %s", path); test_alloc(pop, size); pmemobj_close(pop); ASSERTeq(pmemobj_check(path, LAYOUT_NAME), 1); /* * To prevent subsequent opens from receiving exactly the same * volatile memory addresses a dummy malloc has to be made. * This can expose issues in which traces of previous volatile * state are leftover in the persistent pool. */ void *heap_touch = MALLOC(1); ASSERTne(pop = pmemobj_open(path, LAYOUT_NAME), NULL); test_free(pop); pmemobj_close(pop); FREE(heap_touch); } DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_many_size_allocs"); if (argc != 2) FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) FATAL("!pmemobj_create: %s", path); test_allocs(pop, path); DONE(NULL); }
int main(int argc, char *argv[]) { const char path[] = "/pmem-fs/myfile"; PMEMobjpool *pop; /* create the pmemobj pool or open it if it already exists */ pop = pmemobj_create(path, LAYOUT_NAME, POOL_SIZE, 0666); if (pop == NULL) pop = pmemobj_open(path, LAYOUT_NAME); if (pop == NULL) { perror(path); exit(1); } /* ... */ pmemobj_close(pop); }
/* * test_create -- allocate all possible objects and log the number. It should * exceed what would be possible on a single zone. * Additionally, free one object so that we can later check that it can be * allocated after the next open. */ static void test_create(const char *path) { PMEMobjpool *pop = NULL; if ((pop = pmemobj_create(path, LAYOUT_NAME, 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid oid; int n = 0; while (1) { if (pmemobj_alloc(pop, &oid, ALLOC_SIZE, 0, NULL, NULL) != 0) break; n++; } UT_OUT("allocated: %d", n); pmemobj_free(&oid); pmemobj_close(pop); }
int main(int argc, char *argv[]) { START(argc, argv, "heap_interrupt"); UT_COMPILE_ERROR_ON(POBJ_LAYOUT_TYPES_NUM(heap_interrupt) != 0); if (argc != 4) UT_FATAL("usage: %s file [cmd: c/o] [scenario]", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; int exists = argv[2][0] == 'o'; int scenario = atoi(argv[3]); if (!exists) { if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(heap_interrupt), 0, S_IWUSR | S_IRUSR)) == NULL) { UT_FATAL("failed to create pool\n"); } scenarios[scenario].create(pop); /* if we get here, something is wrong with function mocking */ UT_ASSERT(0); } else { if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(heap_interrupt))) == NULL) { UT_FATAL("failed to open pool\n"); } scenarios[scenario].verify(pop); } pmemobj_close(pop); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_ctl_alignment"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; if ((pop = pmemobj_create(path, LAYOUT, PMEMOBJ_MIN_POOL * 10, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); test_fail(); test_aligned_allocs(1024, 512, POBJ_HEADER_NONE); test_aligned_allocs(1024, 512, POBJ_HEADER_COMPACT); test_aligned_allocs(64, 64, POBJ_HEADER_COMPACT); pmemobj_close(pop); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_pvector"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); const char *path = argv[1]; PMEMobjpool *pop; if ((pop = pmemobj_create(path, "obj_pvector", PMEMOBJ_MIN_POOL * 3, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid root = pmemobj_root(pop, sizeof(struct test_root)); struct test_root *r = (struct test_root *)pmemobj_direct(root); UT_ASSERTne(r, NULL); struct pvector_context *ctx = pvector_new(pop, &r->vec); uint64_t *val = pvector_push_back(ctx); *val = 5; val = pvector_push_back(ctx); *val = 10; val = pvector_push_back(ctx); *val = 15; uint64_t v; int n = 0; for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) { if (n == 0) UT_ASSERTeq(v, 5); if (n == 1) UT_ASSERTeq(v, 10); if (n == 2) UT_ASSERTeq(v, 15); if (n == 3) UT_ASSERT(0); n++; } uint64_t removed = pvector_pop_back(ctx, NULL); UT_ASSERTeq(removed, 15); n = 0; for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) { if (n == 0) UT_ASSERTeq(v, 5); if (n == 1) UT_ASSERTeq(v, 10); if (n == 3) UT_ASSERT(0); n++; } while (pvector_pop_back(ctx, vec_zero_entry) != 0) ; pvector_delete(ctx); ctx = pvector_new(pop, &r->vec); for (int i = 0; i < PVECTOR_INSERT_VALUES; ++i) { val = pvector_push_back(ctx); UT_ASSERTne(val, NULL); *val = i; pmemobj_persist(pop, val, sizeof(*val)); } n = 0; for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) { UT_ASSERTeq(v, n); n++; } n = 0; for (int i = PVECTOR_INSERT_VALUES - 1; i >= 0; --i) { v = pvector_pop_back(ctx, NULL); UT_ASSERTeq(v, i); } UT_ASSERTeq(pvector_first(ctx), 0); pvector_delete(ctx); pmemobj_close(pop); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_constructor"); if (argc != 2) UT_FATAL("usage: %s file-name", argv[0]); const char *path = argv[1]; PMEMobjpool *pop = NULL; int ret; TOID(struct root) root; TOID(struct node) node; if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(constr), 0, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); /* * Allocate memory until OOM, so we can check later if the alloc * cancellation didn't damage the heap in any way. */ int allocs = 0; while (pmemobj_alloc(pop, NULL, sizeof (struct node), 1, NULL, NULL) == 0) allocs++; UT_ASSERTne(allocs, 0); PMEMoid oid; PMEMoid next; POBJ_FOREACH_SAFE(pop, oid, next) pmemobj_free(&oid); errno = 0; root.oid = pmemobj_root_construct(pop, sizeof (struct root), root_constr_cancel, NULL); UT_ASSERT(TOID_IS_NULL(root)); UT_ASSERTeq(errno, ECANCELED); errno = 0; ret = pmemobj_alloc(pop, NULL, sizeof (struct node), 1, node_constr_cancel, NULL); UT_ASSERTeq(ret, -1); UT_ASSERTeq(errno, ECANCELED); /* the same number of allocations should be possible. */ while (pmemobj_alloc(pop, NULL, sizeof (struct node), 1, NULL, NULL) == 0) allocs--; UT_ASSERTeq(allocs, 0); POBJ_FOREACH_SAFE(pop, oid, next) pmemobj_free(&oid); root.oid = pmemobj_root_construct(pop, sizeof (struct root), NULL, NULL); UT_ASSERT(!TOID_IS_NULL(root)); errno = 0; node.oid = pmemobj_list_insert_new(pop, offsetof(struct node, next), &D_RW(root)->list, OID_NULL, 0, sizeof (struct node), 1, node_constr_cancel, NULL); UT_ASSERT(TOID_IS_NULL(node)); UT_ASSERTeq(errno, ECANCELED); pmemobj_close(pop); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_tx_flow"); if (argc != 2) FATAL("usage: %s [file]", argv[0]); PMEMobjpool *pop; if ((pop = pmemobj_create(argv[1], LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR)) == NULL) FATAL("!pmemobj_create"); int a = 0; int b = 0; int c = 0; TX_BEGIN(pop) { a = TEST_VALUE_A; } TX_ONCOMMIT { ASSERT(a == TEST_VALUE_A); b = TEST_VALUE_B; } TX_ONABORT { /* not called */ a = TEST_VALUE_B; } TX_FINALLY { ASSERT(b == TEST_VALUE_B); c = TEST_VALUE_C; } TX_END ASSERT(a == TEST_VALUE_A); ASSERT(b == TEST_VALUE_B); ASSERT(c == TEST_VALUE_C); a = 0; b = 0; c = 0; TX_BEGIN(pop) { a = TEST_VALUE_A; pmemobj_tx_abort(EINVAL); a = TEST_VALUE_B; } TX_ONCOMMIT { /* not called */ a = TEST_VALUE_B; } TX_ONABORT { ASSERT(a == TEST_VALUE_A); b = TEST_VALUE_B; } TX_FINALLY { ASSERT(b == TEST_VALUE_B); c = TEST_VALUE_C; } TX_END ASSERT(a == TEST_VALUE_A); ASSERT(b == TEST_VALUE_B); ASSERT(c == TEST_VALUE_C); a = 0; b = 0; c = 0; TX_BEGIN(pop) { TX_BEGIN(pop) { a = TEST_VALUE_A; } TX_ONCOMMIT { ASSERT(a == TEST_VALUE_A); b = TEST_VALUE_B; } TX_END } TX_ONCOMMIT { c = TEST_VALUE_C; } TX_END ASSERT(a == TEST_VALUE_A); ASSERT(b == TEST_VALUE_B); ASSERT(c == TEST_VALUE_C); a = 0; b = 0; c = 0; TX_BEGIN(pop) { a = TEST_VALUE_C; TX_BEGIN(pop) { a = TEST_VALUE_A; pmemobj_tx_abort(EINVAL); a = TEST_VALUE_B; } TX_ONCOMMIT { /* not called */ a = TEST_VALUE_C; } TX_ONABORT { ASSERT(a == TEST_VALUE_A); b = TEST_VALUE_B; } TX_FINALLY { ASSERT(b == TEST_VALUE_B); c = TEST_VALUE_C; } TX_END a = TEST_VALUE_B; } TX_ONCOMMIT { /* not called */ ASSERT(a == TEST_VALUE_A); c = TEST_VALUE_C; } TX_ONABORT { ASSERT(a == TEST_VALUE_A); ASSERT(b == TEST_VALUE_B); ASSERT(c == TEST_VALUE_C); a = TEST_VALUE_B; } TX_FINALLY { ASSERT(a == TEST_VALUE_B); b = TEST_VALUE_A; } TX_END ASSERT(a == TEST_VALUE_B); ASSERT(b == TEST_VALUE_A); ASSERT(c == TEST_VALUE_C); a = 0; b = 0; c = 0; pmemobj_tx_begin(pop, NULL, TX_LOCK_NONE); pmemobj_tx_abort(EINVAL); ASSERT(pmemobj_tx_stage() == TX_STAGE_ONABORT); a = TEST_VALUE_A; pmemobj_tx_end(); ASSERT(a == TEST_VALUE_A); pmemobj_close(pop); DONE(NULL); }
int main(int argc, char *argv[]) { unsigned int res = 0; PMEMobjpool *pop; const char *path; START(argc, argv, "ex_linkedlist"); if (argc != 2) { UT_FATAL("usage: %s file-name", argv[0]); } path = argv[1]; if (access(path, F_OK) != 0) { if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(list), PMEMOBJ_MIN_POOL, 0666)) == NULL) { UT_FATAL("!pmemobj_create: %s", path); } } else { if ((pop = pmemobj_open(path, POBJ_LAYOUT_NAME(list))) == NULL) { UT_FATAL("!pmemobj_open: %s", path); } } TOID(struct base) base = POBJ_ROOT(pop, struct base); TOID(struct tqueuehead) tqhead = D_RO(base)->tqueue; TOID(struct slisthead) slhead = D_RO(base)->slist; TX_BEGIN(pop) { tqhead = TX_NEW(struct tqueuehead); slhead = TX_NEW(struct slisthead); } TX_ONABORT { abort(); } TX_END init_tqueue(pop, tqhead); init_slist(pop, slhead); int i = 0; TOID(struct tqnode) tqelement; POBJ_TAILQ_FOREACH(tqelement, tqhead, tnd) { if (D_RO(tqelement)->data != expectedResTQ[i]) { res = 1; break; } i++; } PRINT_RES(res, tail queue); i = 0; res = 0; TOID(struct snode) slelement; POBJ_SLIST_FOREACH(slelement, slhead, snd) { if (D_RO(slelement)->data != expectedResSL[i]) { res = 1; break; } i++; } PRINT_RES(res, singly linked list); pmemobj_close(pop); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "obj_direct"); if (argc != 3) UT_FATAL("usage: %s [directory] [# of pools]", argv[0]); int npools = atoi(argv[2]); const char *dir = argv[1]; int r; pthread_mutex_init(&lock1, NULL); pthread_mutex_init(&lock2, NULL); pthread_cond_init(&sync_cond1, NULL); pthread_cond_init(&sync_cond2, NULL); cond1 = cond2 = 0; PMEMobjpool **pops = MALLOC(npools * sizeof(PMEMobjpool *)); UT_ASSERTne(pops, NULL); char path[MAX_PATH_LEN]; for (int i = 0; i < npools; ++i) { snprintf(path, MAX_PATH_LEN, "%s/testfile%d", dir, i); pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); if (pops[i] == NULL) UT_FATAL("!pmemobj_create"); } PMEMoid *oids = MALLOC(npools * sizeof(PMEMoid)); UT_ASSERTne(oids, NULL); PMEMoid *tmpoids = MALLOC(npools * sizeof(PMEMoid)); UT_ASSERTne(tmpoids, NULL); oids[0] = OID_NULL; UT_ASSERTeq(pmemobj_direct(oids[0]), NULL); for (int i = 0; i < npools; ++i) { oids[i] = (PMEMoid) {pops[i]->uuid_lo, 0}; UT_ASSERTeq(pmemobj_direct(oids[i]), NULL); uint64_t off = pops[i]->heap_offset; oids[i] = (PMEMoid) {pops[i]->uuid_lo, off}; UT_ASSERTeq((char *)pmemobj_direct(oids[i]) - off, (char *)pops[i]); r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL); UT_ASSERTeq(r, 0); } r = pmemobj_alloc(pops[0], &thread_oid, 100, 2, NULL, NULL); UT_ASSERTeq(r, 0); UT_ASSERTne(pmemobj_direct(thread_oid), NULL); pthread_t t; PTHREAD_CREATE(&t, NULL, test_worker, NULL); /* wait for the worker thread to perform the first check */ pthread_mutex_lock(&lock1); while (!cond1) pthread_cond_wait(&sync_cond1, &lock1); pthread_mutex_unlock(&lock1); for (int i = 0; i < npools; ++i) { UT_ASSERTne(pmemobj_direct(tmpoids[i]), NULL); pmemobj_free(&tmpoids[i]); UT_ASSERTeq(pmemobj_direct(tmpoids[i]), NULL); pmemobj_close(pops[i]); UT_ASSERTeq(pmemobj_direct(oids[i]), NULL); } /* signal the worker that we're free and closed */ pthread_mutex_lock(&lock2); cond2 = 1; pthread_cond_signal(&sync_cond2); pthread_mutex_unlock(&lock2); PTHREAD_JOIN(t, NULL); pthread_cond_destroy(&sync_cond1); pthread_cond_destroy(&sync_cond2); pthread_mutex_destroy(&lock1); pthread_mutex_destroy(&lock2); FREE(pops); FREE(tmpoids); FREE(oids); DONE(NULL); }
int main(int argc, char *argv[]) { START(argc, argv, "out_err_mt"); if (argc != 5) UT_FATAL("usage: %s filename1 filename2 filename3 dir", argv[0]); PMEMobjpool *pop = pmemobj_create(argv[1], "test", PMEMOBJ_MIN_POOL, 0666); PMEMlogpool *plp = pmemlog_create(argv[2], PMEMLOG_MIN_POOL, 0666); PMEMblkpool *pbp = pmemblk_create(argv[3], 128, PMEMBLK_MIN_POOL, 0666); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ VMEM *vmp = vmem_create(argv[4], VMEM_MIN_POOL); #endif util_init(); pmem_check_version(10000, 0); pmemobj_check_version(10001, 0); pmemlog_check_version(10002, 0); pmemblk_check_version(10003, 0); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ vmem_check_version(10004, 0); #endif pmempool_check_version(10005, 0); print_errors("version check"); void *ptr = NULL; /* * We are testing library error reporting and we don't want this test * to fail under memcheck. */ VALGRIND_DO_DISABLE_ERROR_REPORTING; pmem_msync(ptr, 1); VALGRIND_DO_ENABLE_ERROR_REPORTING; print_errors("pmem_msync"); pmemlog_append(plp, NULL, PMEMLOG_MIN_POOL); print_errors("pmemlog_append"); size_t nblock = pmemblk_nblock(pbp); pmemblk_set_error(pbp, nblock + 1); print_errors("pmemblk_set_error"); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ VMEM *vmp2 = vmem_create_in_region(NULL, 1); UT_ASSERTeq(vmp2, NULL); print_errors("vmem_create_in_region"); #endif run_mt_test(do_test); pmemobj_close(pop); pmemlog_close(plp); pmemblk_close(pbp); #ifndef _WIN32 /* XXX - vmem not implemented in windows yet */ vmem_delete(vmp); #endif PMEMpoolcheck *ppc; struct pmempool_check_args args = {0, }; ppc = pmempool_check_init(&args, sizeof(args) / 2); UT_ASSERTeq(ppc, NULL); print_errors("pmempool_check_init"); DONE(NULL); }
/* * pmemlog_create -- pool create wrapper */ PMEMlogpool * pmemlog_create(const char *path, size_t poolsize, mode_t mode) { return (PMEMlogpool *)pmemobj_create(path, LAYOUT_NAME, poolsize, mode); }
/* * pobj_init - common part of the benchmark initialization functions. * Parses command line arguments, set variables and creates persistent pools. */ static int pobj_init(struct benchmark *bench, struct benchmark_args *args) { unsigned i = 0; size_t psize; size_t n_objs; assert(bench != nullptr); assert(args != nullptr); enum file_type type = util_file_get_type(args->fname); if (type == OTHER_ERROR) { fprintf(stderr, "could not check type of file %s\n", args->fname); return -1; } auto *bench_priv = (struct pobj_bench *)malloc(sizeof(struct pobj_bench)); if (bench_priv == nullptr) { perror("malloc"); return -1; } assert(args->opts != nullptr); bench_priv->args_priv = (struct pobj_args *)args->opts; bench_priv->args_priv->obj_size = args->dsize; bench_priv->args_priv->range = bench_priv->args_priv->min_size > 0 ? true : false; bench_priv->n_pools = !bench_priv->args_priv->one_pool ? args->n_threads : 1; bench_priv->pool = bench_priv->n_pools > 1 ? diff_num : one_num; bench_priv->obj = !bench_priv->args_priv->one_obj ? diff_num : one_num; if ((args->is_poolset || type == TYPE_DEVDAX) && bench_priv->n_pools > 1) { fprintf(stderr, "cannot use poolset nor device dax for multiple pools," " please use -P|--one-pool option instead"); goto free_bench_priv; } /* * Multiplication by FACTOR prevents from out of memory error * as the actual size of the allocated persistent objects * is always larger than requested. */ n_objs = bench_priv->args_priv->n_objs; if (bench_priv->n_pools == 1) n_objs *= args->n_threads; psize = PMEMOBJ_MIN_POOL + n_objs * args->dsize * args->n_threads * FACTOR; /* assign type_number determining function */ bench_priv->type_mode = parse_type_mode(bench_priv->args_priv->type_num); switch (bench_priv->type_mode) { case MAX_TYPE_MODE: fprintf(stderr, "unknown type mode"); goto free_bench_priv; case TYPE_MODE_RAND: if (random_types(bench_priv, args)) goto free_bench_priv; break; default: bench_priv->random_types = nullptr; } bench_priv->fn_type_num = type_mode_func[bench_priv->type_mode]; /* assign size determining function */ bench_priv->fn_size = bench_priv->args_priv->range ? range_size : static_size; bench_priv->rand_sizes = nullptr; if (bench_priv->args_priv->range) { if (bench_priv->args_priv->min_size > args->dsize) { fprintf(stderr, "Invalid allocation size"); goto free_random_types; } bench_priv->rand_sizes = rand_sizes(bench_priv->args_priv->min_size, bench_priv->args_priv->obj_size, bench_priv->args_priv->n_objs); if (bench_priv->rand_sizes == nullptr) goto free_random_types; } assert(bench_priv->n_pools > 0); bench_priv->pop = (PMEMobjpool **)calloc(bench_priv->n_pools, sizeof(PMEMobjpool *)); if (bench_priv->pop == nullptr) { perror("calloc"); goto free_random_sizes; } bench_priv->sets = (const char **)calloc(bench_priv->n_pools, sizeof(const char *)); if (bench_priv->sets == nullptr) { perror("calloc"); goto free_pop; } if (bench_priv->n_pools > 1) { assert(!args->is_poolset); if (util_file_mkdir(args->fname, DIR_MODE) != 0) { fprintf(stderr, "cannot create directory\n"); goto free_sets; } size_t path_len = (strlen(PART_NAME) + strlen(args->fname)) + MAX_DIGITS + 1; for (i = 0; i < bench_priv->n_pools; i++) { bench_priv->sets[i] = (char *)malloc(path_len * sizeof(char)); if (bench_priv->sets[i] == nullptr) { perror("malloc"); goto free_sets; } int ret = snprintf((char *)bench_priv->sets[i], path_len, "%s%s%02x", args->fname, PART_NAME, i); if (ret < 0 || ret >= (int)path_len) { perror("snprintf"); goto free_sets; } bench_priv->pop[i] = pmemobj_create(bench_priv->sets[i], LAYOUT_NAME, psize, FILE_MODE); if (bench_priv->pop[i] == nullptr) { perror(pmemobj_errormsg()); goto free_sets; } } } else { if (args->is_poolset || type == TYPE_DEVDAX) { if (args->fsize < psize) { fprintf(stderr, "file size too large\n"); goto free_pools; } psize = 0; } bench_priv->sets[0] = args->fname; bench_priv->pop[0] = pmemobj_create( bench_priv->sets[0], LAYOUT_NAME, psize, FILE_MODE); if (bench_priv->pop[0] == nullptr) { perror(pmemobj_errormsg()); goto free_pools; } } pmembench_set_priv(bench, bench_priv); return 0; free_sets: for (; i > 0; i--) { pmemobj_close(bench_priv->pop[i - 1]); free((char *)bench_priv->sets[i - 1]); } free_pools: free(bench_priv->sets); free_pop: free(bench_priv->pop); free_random_sizes: free(bench_priv->rand_sizes); free_random_types: free(bench_priv->random_types); free_bench_priv: free(bench_priv); return -1; }