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])); } }
/* * pocli_pmemobj_root -- pmemobj_root() command */ static enum pocli_ret pocli_pmemobj_root(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 2) return POCLI_ERR_ARGS; size_t size = 0; enum pocli_ret ret; ret = pocli_args_size(args, 1, &size); if (ret) return ret; PMEMoid root = pmemobj_root(ctx->pop, size); if (OID_IS_NULL(root)) return pocli_err(ctx, POCLI_ERR_CMD, "pmemobj_root failed\n"); ctx->root = root; pocli_printf(ctx, "%s(%llu): off = 0x%jx uuid = 0x%jx\n", args->argv[0], size, ctx->root.off, ctx->root.pool_uuid_lo); return POCLI_RET_OK; }
/* * pocli_str_root_print -- print a string stored in the root object data */ static enum pocli_ret pocli_str_root_print(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 3) return POCLI_ERR_ARGS; size_t offset = 0; enum pocli_ret ret = pocli_args_size(args, 1, &offset); if (ret) return ret; size_t len = 0; ret = pocli_args_number(args, 2, &len); if (ret) return ret; size_t root_size = pmemobj_root_size(ctx->pop); if (offset + len > root_size) return POCLI_ERR_ARGS; PMEMoid root = pmemobj_root(ctx->pop, root_size); assert(!OID_IS_NULL(root)); char *root_data = pmemobj_direct(root); char *buff = malloc(len + 1); memcpy(buff, root_data + offset, len); buff[len] = '\0'; printf("%s\n", buff); return ret; }
/* * pocli_str_root_copy -- copy a string into a root object data */ static enum pocli_ret pocli_str_root_copy(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 3) return POCLI_ERR_ARGS; size_t offset = 0; enum pocli_ret ret = pocli_args_size(args, 1, &offset); if (ret) return ret; const char *str = args->argv[2]; if (str == NULL) return POCLI_ERR_ARGS; size_t len = strlen(str); size_t root_size = pmemobj_root_size(ctx->pop); if (offset + len > root_size) return POCLI_ERR_ARGS; PMEMoid root = pmemobj_root(ctx->pop, root_size); assert(!OID_IS_NULL(root)); char *root_data = pmemobj_direct(root); pmemobj_memcpy_persist(ctx->pop, root_data + offset, str, len); return ret; }
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_list_insert_new -- pmemobj_list_insert_new() command */ static enum pocli_ret pocli_pmemobj_list_insert_new(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 7) return POCLI_ERR_ARGS; PMEMoid nulloid = OID_NULL; PMEMoid *dest; PMEMoid *oid; PMEMoid *head_oid; enum pocli_ret ret; uint64_t before; uint64_t type_num; uint64_t size; if ((ret = pocli_args_obj(ctx, args, 1, &oid))) return ret; if (oid == &ctx->root) return pocli_err(ctx, POCLI_ERR_ARGS, "cannot allocate to root object\n"); if ((ret = pocli_args_obj(ctx, args, 2, &head_oid))) return ret; struct plist *head = pmemobj_direct(*head_oid); if ((ret = pocli_args_list_elm(ctx, args, 3, &dest, head))) return ret; if (dest == NULL) dest = &nulloid; if ((ret = pocli_args_number(args, 4, &before))) return ret; if (before > 1) return pocli_err(ctx, POCLI_ERR_ARGS, "Before flag different than 0 or 1\n"); if ((ret = pocli_args_number(args, 5, &type_num))) return ret; if ((ret = pocli_args_number(args, 6, &size))) return ret; *oid = pmemobj_list_insert_new(ctx->pop, offsetof(struct item, field), head, *dest, (int)before, size, type_num, NULL, NULL); if (OID_IS_NULL(*oid)) return pocli_err(ctx, POCLI_ERR_ARGS, "pmemobj_list_insert_new() failed\n"); pocli_printf(ctx, "%s(%s, %p, %u, %llu, %zu): off = 0x%jx uuid = 0x%jx" " ptr = %p\n", args->argv[0], args->argv[2], dest, before, type_num, size, oid->off, oid->pool_uuid_lo, pmemobj_direct(*oid)); return ret; }
/* * pmemlog_appendv -- add gathered data to a log memory pool */ int pmemlog_appendv(PMEMlogpool *plp, const struct iovec *iov, int iovcnt) { PMEMobjpool *pop = (PMEMobjpool *)plp; PMEMoid baseoid = pmemobj_root(pop, sizeof (struct base)); struct base *bp = pmemobj_direct(baseoid); /* set the return point */ jmp_buf env; if (setjmp(env)) { /* end the transaction */ pmemobj_tx_end(); return 1; } /* begin a transaction, also acquiring the write lock for the log */ pmemobj_tx_begin(pop, env, TX_LOCK_RWLOCK, &bp->rwlock, TX_LOCK_NONE); /* add the base object to the undo log - once for the transaction */ pmemobj_tx_add_range(baseoid, 0, sizeof (struct base)); /* add the tail entry once to the undo log, if it is set */ if (!OID_IS_NULL(bp->tail)) pmemobj_tx_add_range(bp->tail, 0, sizeof (struct log)); /* append the data */ for (int i = 0; i < iovcnt; ++i) { char *buf = iov[i].iov_base; size_t count = iov[i].iov_len; /* allocate the new node to be inserted */ PMEMoid log = pmemobj_tx_alloc(count + sizeof (struct log_hdr), LOG_TYPE); struct log *logp = pmemobj_direct(log); logp->hdr.size = count; memcpy(logp->data, buf, count); logp->hdr.next = OID_NULL; if (bp->tail.off == 0) { bp->head = log; /* update head */ } else { ((struct log *)pmemobj_direct(bp->tail))->hdr.next = log; } bp->tail = log; /* update tail */ bp->bytes_written += count; } pmemobj_tx_commit(); pmemobj_tx_end(); return 0; }
/* * pocli_pmemobj_first -- pmemobj_first() command */ static enum pocli_ret pocli_pmemobj_first(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 1) return POCLI_ERR_ARGS; PMEMoid oidp = pmemobj_first(ctx->pop); if (OID_IS_NULL(oidp)) return pocli_err(ctx, POCLI_ERR_ARGS, "pmemobj_first() failed\n"); pocli_printf(ctx, "%s: off = 0x%llx uuid = 0x%llx\n", args->argv[0], oidp.off, oidp.pool_uuid_lo); return POCLI_RET_OK; }
/* * pmemobj_vg_boot -- (internal) notify Valgrind about pool objects */ static void pmemobj_vg_boot(struct pmemobjpool *pop) { if (!On_valgrind) return; LOG(4, "pop %p", pop); PMEMoid oid; int rs = pmemobj_root_size(pop); if (rs) { oid = pmemobj_root(pop, rs); pmemobj_vg_register_object(pop, oid, 1); } for (int i = 0; i < PMEMOBJ_NUM_OID_TYPES; ++i) { for (oid = pmemobj_first(pop, i); !OID_IS_NULL(oid); oid = pmemobj_next(oid)) pmemobj_vg_register_object(pop, oid, 0); } if (getenv("PMEMOBJ_VG_CHECK_UNDEF")) pmemobj_vg_check_no_undef(pop); }
static void * tx_snap(void *arg) { volatile int locked; for (int i = 0; i < LOOPS; ++i) { locked = 0; TX_BEGIN(pop) { pthread_mutex_lock(&mtx); locked = 1; if (!OID_IS_NULL(tab)) pmemobj_tx_add_range(tab, 0, 8); } TX_ONCOMMIT { if (locked) pthread_mutex_unlock(&mtx); } TX_ONABORT { if (locked) pthread_mutex_unlock(&mtx); } TX_END locked = 0; } return NULL; }
int main(int argc, char *argv[]) { #ifdef _WIN32 wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc); for (int i = 0; i < argc; i++) { argv[i] = util_toUTF8(wargv[i]); if (argv[i] == NULL) { for (i--; i >= 0; i--) free(argv[i]); fprintf(stderr, "Error during arguments conversion\n"); return 1; } } #endif int opt; int tmpi; long long tmpl; int ret = 0; size_t size = 0; size_t root_size = 0; unsigned type_num = 0; char exit_at = '\0'; int do_set = 0; int do_free = 0; if (argc < 2) { USAGE(); ret = 1; goto end; } while ((opt = getopt(argc, argv, "r:o:t:e:sf")) != -1) { switch (opt) { case 'r': tmpl = atoll(optarg); if (tmpl < 0) { USAGE(); ret = 1; goto end; } root_size = (size_t)tmpl; break; case 'o': tmpl = atoll(optarg); if (tmpl < 0) { USAGE(); ret = 1; goto end; } size = (size_t)tmpl; break; case 't': tmpi = atoi(optarg); if (tmpi < 0) { USAGE(); ret = 1; goto end; } type_num = (unsigned)tmpi; break; case 'e': exit_at = optarg[0]; break; case 's': do_set = 1; break; case 'f': do_free = 1; break; default: USAGE(); ret = 1; goto end; } } char *file = argv[optind]; PMEMobjpool *pop; if ((pop = pmemobj_open(file, NULL)) == NULL) { fprintf(stderr, "pmemobj_open: %s\n", pmemobj_errormsg()); ret = 1; goto end; } if (root_size) { PMEMoid oid = pmemobj_root(pop, root_size); if (OID_IS_NULL(oid)) { fprintf(stderr, "pmemobj_root: %s\n", pmemobj_errormsg()); ret = 1; goto end; } } if (size) { PMEMoid oid; TX_BEGIN(pop) { oid = pmemobj_tx_alloc(size, type_num); if (exit_at == 'a') exit(1); } TX_END if (OID_IS_NULL(oid)) { fprintf(stderr, "pmemobj_tx_alloc: %s\n", pmemobj_errormsg()); ret = 1; goto end; } if (do_set) { TX_BEGIN(pop) { pmemobj_tx_add_range(oid, 0, size); if (exit_at == 's') exit(1); } TX_END } if (do_free) { TX_BEGIN(pop) { pmemobj_tx_free(oid); if (exit_at == 'f') exit(1); } TX_END } } pmemobj_close(pop); end: #ifdef _WIN32 for (int i = argc; i > 0; i--) free(argv[i - 1]); #endif return ret; }
int main(int argc, char *argv[]) { int opt; int tmpi; long long tmpl; size_t size = 0; size_t root_size = 0; unsigned int type_num = 0; char exit_at = '\0'; int do_set = 0; int do_free = 0; if (argc < 2) { USAGE(); return -1; } while ((opt = getopt(argc, argv, "r:o:t:e:sf")) != -1) { switch (opt) { case 'r': tmpl = atoll(optarg); if (tmpl < 0) { USAGE(); return -1; } root_size = (size_t)tmpl; break; case 'o': tmpl = atoll(optarg); if (tmpl < 0) { USAGE(); return -1; } size = (size_t)tmpl; break; case 't': tmpi = atoi(optarg); if (tmpi < 0) { USAGE(); return -1; } type_num = (unsigned)tmpi; break; case 'e': exit_at = optarg[0]; break; case 's': do_set = 1; break; case 'f': do_free = 1; break; default: USAGE(); return -1; } } char *file = argv[optind]; PMEMobjpool *pop; if ((pop = pmemobj_open(file, NULL)) == NULL) { fprintf(stderr, "pmemobj_open: %s\n", pmemobj_errormsg()); return -1; } if (root_size) { PMEMoid oid = pmemobj_root(pop, root_size); if (OID_IS_NULL(oid)) { fprintf(stderr, "pmemobj_root: %s\n", pmemobj_errormsg()); return -1; } } if (size) { PMEMoid oid; TX_BEGIN(pop) { oid = pmemobj_tx_alloc(size, type_num); if (exit_at == 'a') exit(1); } TX_END if (OID_IS_NULL(oid)) { fprintf(stderr, "pmemobj_tx_alloc: %s\n", pmemobj_errormsg()); return -1; } if (do_set) { TX_BEGIN(pop) { pmemobj_tx_add_range(oid, 0, size); if (exit_at == 's') exit(1); } TX_END } if (do_free) { TX_BEGIN(pop) { pmemobj_tx_free(oid); if (exit_at == 'f') exit(1); } TX_END } } pmemobj_close(pop); return 0; }