static void * tx_alloc_free(void *arg) { volatile int locked; for (int i = 0; i < LOOPS; ++i) { locked = 0; TX_BEGIN(pop) { pthread_mutex_lock(&mtx); locked = 1; tab = pmemobj_tx_alloc(128, 1); } TX_ONCOMMIT { if (locked) pthread_mutex_unlock(&mtx); } TX_ONABORT { if (locked) pthread_mutex_unlock(&mtx); } TX_END locked = 0; TX_BEGIN(pop) { pthread_mutex_lock(&mtx); locked = 1; pmemobj_tx_free(tab); tab = OID_NULL; } TX_ONCOMMIT { if (locked) pthread_mutex_unlock(&mtx); } TX_ONABORT { if (locked) pthread_mutex_unlock(&mtx); } TX_END } return NULL; }
/* * pmemlog_rewind -- discard all data, resetting a log memory pool to empty */ void pmemlog_rewind(PMEMlogpool *plp) { 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; } /* 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 root object to the undo log */ pmemobj_tx_add_range(baseoid, 0, sizeof (struct base)); /* free all log nodes */ while (bp->head.off != 0) { PMEMoid nextoid = ((struct log *)pmemobj_direct(bp->head))->hdr.next; pmemobj_tx_free(bp->head); bp->head = nextoid; } bp->head = OID_NULL; bp->tail = OID_NULL; bp->bytes_written = 0; pmemobj_tx_commit(); pmemobj_tx_end(); }
/* * pocli_pmemobj_tx_free -- pmemobj_tx_free() command */ static enum pocli_ret pocli_pmemobj_tx_free(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 2) return POCLI_ERR_ARGS; if (pmemobj_tx_stage() != TX_STAGE_WORK) return pocli_err(ctx, POCLI_ERR_ARGS, "cannot use in stage different than TX_STAGE_WORK\n"); PMEMoid *oidp = NULL; enum pocli_ret ret; ret = pocli_args_obj(ctx, args, 1, &oidp); if (ret) return ret; if (oidp == &ctx->root) return pocli_err(ctx, POCLI_ERR_ARGS, "cannot free root object\n"); int r = pmemobj_tx_free(*oidp); if (r != POCLI_RET_OK) return pocli_err(ctx, POCLI_ERR_ARGS, "pmemobj_tx_free() failed\n"); 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(typename detail::pp_if_not_array<T>::type ptr) { if (pmemobj_tx_stage() != TX_STAGE_WORK) throw transaction_scope_error( "refusing to free " "memory outside of transaction scope"); if (ptr == nullptr) return; /* * At this point, everything in the object should be tracked * and reverted on transaction abort. */ ptr->T::~T(); if (pmemobj_tx_free(*ptr.raw_ptr()) != 0) throw transaction_alloc_error("failed to delete " "persistent memory object"); }
typename detail::pp_if_not_array<T>::type make_persistent(Args &&... args) { if (pmemobj_tx_stage() != TX_STAGE_WORK) throw transaction_scope_error( "refusing to allocate " "memory outside of transaction scope"); persistent_ptr<T> ptr = pmemobj_tx_alloc(sizeof(T), detail::type_num<T>()); if (ptr == nullptr) throw transaction_alloc_error("failed to allocate " "persistent memory object"); try { new (ptr.get()) T(args...); } catch (...) { pmemobj_tx_free(*ptr.raw_ptr()); throw; } return ptr; }
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; }