static void allocate_objects(PMEMobjpool *pop, size_t size_min, size_t size_max) { size_t allocated_total = 0; size_t sstart = 0; PMEMoid oid = pmemobj_root(pop, 1); uint64_t uuid_lo = oid.pool_uuid_lo; while (allocated_total < ALLOC_TOTAL) { size_t s = RRAND(seed, size_max, size_min); pmemobj_alloc(pop, &oid, s, 0, NULL, NULL); s = pmemobj_alloc_usable_size(oid); UT_ASSERTeq(OID_IS_NULL(oid), 0); objects[nobjects++] = oid.off; UT_ASSERT(nobjects < MAX_OBJECTS); allocated_total += s; allocated_current += s; if (allocated_current > ALLOC_CURR) { shuffle_objects(sstart, nobjects); for (int i = 0; i < FREES_P; ++i) { oid.pool_uuid_lo = uuid_lo; oid.off = remove_last(); allocated_current -= pmemobj_alloc_usable_size(oid); pmemobj_free(&oid); } sstart = nobjects; } } }
/* * pocli_pmemobj_free -- pmemobj_free() command */ static enum pocli_ret pocli_pmemobj_free(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 2) return POCLI_ERR_ARGS; PMEMoid *oidp = NULL; enum pocli_ret ret; ret = pocli_args_obj(ctx, args, 1, &oidp); if (ret) return ret; if (oidp == NULL) return pocli_err(ctx, POCLI_ERR_ARGS, "NULL pointer not allowed here\n"); if (oidp == &ctx->root) return pocli_err(ctx, POCLI_ERR_ARGS, "cannot free root object\n"); pmemobj_free(oidp); pocli_printf(ctx, "%s(%p): off = 0x%llx uuid = 0x%llx\n", args->argv[0], oidp, oidp->off, oidp->pool_uuid_lo); return ret; }
void delete_persistent_atomic(typename detail::pp_if_array<T>::type &ptr, std::size_t N) { /* we CAN'T call destructor */ pmemobj_free(ptr.raw_ptr()); }
static void test_allocs(PMEMobjpool *pop, const char *path) { PMEMoid oid[TEST_ALLOC_SIZE]; if (pmemobj_alloc(pop, &oid[0], 0, 0, NULL, NULL) == 0) UT_FATAL("pmemobj_alloc(0) succeeded"); for (int i = 1; i < TEST_ALLOC_SIZE; ++i) { struct cargs args = { i }; if (pmemobj_alloc(pop, &oid[i], i, 0, test_constructor, &args) != 0) UT_FATAL("!pmemobj_alloc"); UT_ASSERT(!OID_IS_NULL(oid[i])); } pmemobj_close(pop); UT_ASSERT(pmemobj_check(path, LAYOUT_NAME) == 1); UT_ASSERT((pop = pmemobj_open(path, LAYOUT_NAME)) != NULL); for (int i = 1; i < TEST_ALLOC_SIZE; ++i) { pmemobj_free(&oid[i]); UT_ASSERT(OID_IS_NULL(oid[i])); } }
FUNC_MOCK_END static void sc0_create(PMEMobjpool *pop) { PMEMoid oids[3]; TX_BEGIN(pop) { oids[0] = pmemobj_tx_alloc(CHUNKSIZE - 100, 0); oids[1] = pmemobj_tx_alloc(CHUNKSIZE - 100, 0); oids[2] = pmemobj_tx_alloc(CHUNKSIZE - 100, 0); } TX_END pmemobj_free(&oids[0]); exit_on_finish = 1; pmemobj_free(&oids[1]); }
void delete_persistent_atomic(typename detail::pp_if_size_array<T>::type &ptr) { if (ptr == nullptr) return; /* we CAN'T call destructor */ pmemobj_free(ptr.raw_ptr()); }
static void test_free(PMEMobjpool *pop) { PMEMoid oid; PMEMoid next; int type_num; POBJ_FOREACH_SAFE(pop, oid, next, type_num) pmemobj_free(&oid); }
/* * pmemlog_rewind -- discard all data, resetting a log memory pool to empty */ void pmemlog_rewind(PMEMlogpool *plp) { PMEMobjpool *pop = (PMEMobjpool *)plp; PMEMoid iter, next; /* go through each list and remove all entries */ POBJ_FOREACH_SAFE(pop, iter, next) { pmemobj_free(&iter); }
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); }
/* * pobj_free_worker -- worker exit function */ static void pobj_free_worker(struct benchmark *bench, struct benchmark_args *args, struct worker_info *worker) { auto *pw = (struct pobj_worker *)worker->priv; auto *bench_priv = (struct pobj_bench *)pmembench_get_priv(bench); for (size_t i = 0; i < bench_priv->args_priv->n_objs; i++) pmemobj_free(&pw->oids[i]); free(pw->oids); free(pw); }
static void * oom_worker(void *arg) { allocated = 0; while (pmemobj_alloc(pop, NULL, TEST_ALLOC_SIZE, 0, NULL, NULL) == 0) allocated++; PMEMoid iter, iter2; int type; POBJ_FOREACH_SAFE(pop, iter, iter2, type) pmemobj_free(&iter); return NULL; }
static void test_all_classes(PMEMobjpool *pop) { for (int i = 1; i <= MAX_BUCKET_MAP_ENTRIES; ++i) { int err; int nallocs = 0; while ((err = pmemobj_alloc(pop, NULL, i * ALLOC_BLOCK_SIZE, 0, NULL, NULL)) == 0) { nallocs++; } UT_ASSERT(nallocs > 0); PMEMoid iter, niter; POBJ_FOREACH_SAFE(pop, iter, niter) { pmemobj_free(&iter); } }
static void delete_objects(PMEMobjpool *pop, float pct) { size_t nfree = (float)nobjects * pct; PMEMoid oid = pmemobj_root(pop, 1); uint64_t uuid_lo = oid.pool_uuid_lo; shuffle_objects(0, nobjects); while (nfree--) { oid.off = remove_last(); oid.pool_uuid_lo = uuid_lo; allocated_current -= pmemobj_alloc_usable_size(oid); pmemobj_free(&oid); } }
static void test_lazy_load(PMEMobjpool *pop, const char *path) { PMEMoid oid[3]; int ret = pmemobj_alloc(pop, &oid[0], LAZY_LOAD_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, &oid[1], LAZY_LOAD_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); ret = pmemobj_alloc(pop, &oid[2], LAZY_LOAD_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); pmemobj_close(pop); UT_ASSERT((pop = pmemobj_open(path, LAYOUT_NAME)) != NULL); pmemobj_free(&oid[1]); ret = pmemobj_alloc(pop, &oid[1], LAZY_LOAD_BIG_SIZE, 0, NULL, NULL); UT_ASSERTeq(ret, 0); }
/* * pobj_init_worker -- worker initialization */ static int pobj_init_worker(struct benchmark *bench, struct benchmark_args *args, struct worker_info *worker) { size_t i, idx = worker->index; auto *bench_priv = (struct pobj_bench *)pmembench_get_priv(bench); auto *pw = (struct pobj_worker *)calloc(1, sizeof(struct pobj_worker)); if (pw == nullptr) { perror("calloc"); return -1; } worker->priv = pw; pw->oids = (PMEMoid *)calloc(bench_priv->args_priv->n_objs, sizeof(PMEMoid)); if (pw->oids == nullptr) { free(pw); perror("calloc"); return -1; } PMEMobjpool *pop = bench_priv->pop[bench_priv->pool(idx)]; for (i = 0; i < bench_priv->args_priv->n_objs; i++) { size_t size = bench_priv->fn_size(bench_priv, i); size_t type = bench_priv->fn_type_num(bench_priv, idx, i); if (pmemobj_alloc(pop, &pw->oids[i], size, type, nullptr, nullptr) != 0) { perror("pmemobj_alloc"); goto out; } } return 0; out: for (; i > 0; i--) pmemobj_free(&pw->oids[i - 1]); free(pw->oids); free(pw); return -1; }
/* * 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, "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((char *)pmemobj_direct(oids[i]) - off, (char *)pops[i]); r = pmemobj_alloc(pops[i], &tmpoids[i], 100, 1, NULL, NULL); ASSERTeq(r, 0); } r = pmemobj_alloc(pops[0], &thread_oid, 100, 2, NULL, NULL); ASSERTeq(r, 0); ASSERTne(pmemobj_direct(thread_oid), NULL); pthread_mutex_lock(&lock); pthread_t t; pthread_create(&t, NULL, test_worker, NULL); /* wait for the thread to perform the first direct */ while (flag) ; 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); } pthread_mutex_unlock(&lock); pthread_join(t, NULL); 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_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); }