Esempio n. 1
0
/*
 * pocli_free -- free main context
 */
static void
pocli_free(struct pocli *pcli)
{
	while (pmemobj_tx_stage() != TX_STAGE_NONE) {
		while (pmemobj_tx_stage() != TX_STAGE_NONE)
			pmemobj_tx_process();
		pmemobj_tx_end();
	}
	pmemobj_close(pcli->ctx.pop);

	free(pcli->inbuf);
	free(pcli);
}
Esempio n. 2
0
/*
 * pocli_pmemobj_tx_strdup -- pmemobj_tx_strdup() command
 */
static enum pocli_ret
pocli_pmemobj_tx_strdup(struct pocli_ctx *ctx, struct pocli_args *args)
{
	if (args->argc != 4)
		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;
	uint64_t type_num;
	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 use root object\n");

	ret = pocli_args_number(args, 3, &type_num);
	if (ret)
		return ret;

	*oidp = pmemobj_tx_strdup(args->argv[2], type_num);

	pocli_printf(ctx, "%s(%s, %llu): off = 0x%llx uuid = 0x%llx\n",
				args->argv[0], args->argv[2], type_num,
				oidp->off, oidp->pool_uuid_lo);
	return ret;
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
/*
 * pocli_pmemobj_do_tx_alloc -- pmemobj_tx_zalloc() and pmemobj_tx_zalloc()
 * commands common part
 */
static enum pocli_ret
pocli_pmemobj_do_tx_alloc(struct pocli_ctx *ctx, struct pocli_args *args,
			PMEMoid (*fn_alloc)(size_t size, uint64_t type_num))
{
	if (args->argc != 4)
		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;
	uint64_t type_num = 0;
	size_t size = 0;
	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 allocate to root object\n");

	ret = pocli_args_size(args, 2, &size);
	if (ret)
		return ret;

	ret = pocli_args_number(args, 3, &type_num);
	if (ret)
		return ret;
	*oidp = fn_alloc(size, type_num);

	pocli_printf(ctx, "%s(%zu, %llu): off = 0x%llx uuid = 0x%llx\n",
		args->argv[0], size, type_num, oidp->off, oidp->pool_uuid_lo);
	return ret;
}
Esempio n. 5
0
/*
 * pocli_pmemobj_tx_end -- pmemobj_tx_end() command
 */
static enum pocli_ret
pocli_pmemobj_tx_end(struct pocli_ctx *ctx, struct pocli_args *args)
{
	if (args->argc != 1)
		return POCLI_ERR_ARGS;

	if (pmemobj_tx_stage() == TX_STAGE_NONE ||
					pmemobj_tx_stage() == TX_STAGE_WORK)
		return pocli_err(ctx, POCLI_ERR_ARGS,
					"transaction in improper stage\n");
	ctx->tx_aborted = false;
	int ret = pmemobj_tx_end();
	pocli_printf(ctx, "%s: %d\n", args->argv[0], ret);

	return POCLI_RET_OK;
}
Esempio n. 6
0
File: p.hpp Progetto: xguo/nvml
		p& operator=(const p &rhs) noexcept
		{
			if (pmemobj_tx_stage() == TX_STAGE_WORK)
				pmemobj_tx_add_range_direct(this, sizeof(T));

			this_type(rhs).swap(*this);

			return *this;
		}
Esempio n. 7
0
inline void
conditional_add_to_tx(const T *that)
{
	if (pmemobj_tx_stage() != TX_STAGE_WORK)
		return;

	/* 'that' is not in any open pool */
	if (!pmemobj_pool_by_ptr(that))
		return;

	if (pmemobj_tx_add_range_direct(that, sizeof(*that)))
		throw transaction_error("Could not add an object to the"
					" transaction.");
}
Esempio n. 8
0
File: obj.c Progetto: jxy859/nvml
/*
 * _pobj_debug_notice -- logs notice message if used inside a transaction
 */
void
_pobj_debug_notice(const char *api_name, const char *file, int line)
{
#ifdef	DEBUG
	if (pmemobj_tx_stage() != TX_STAGE_NONE) {
		if (file)
			LOG(4, "Notice: non-transactional API"
				" used inside a transaction (%s in %s:%d)",
				api_name, file, line);
		else
			LOG(4, "Notice: non-transactional API"
				" used inside a transaction (%s)", api_name);
	}
#endif /* DEBUG */
}
Esempio n. 9
0
/*
 * pocli_pmemobj_tx_commit -- pmemobj_tx_commit() command
 */
static enum pocli_ret
pocli_pmemobj_tx_commit(struct pocli_ctx *ctx, struct pocli_args *args)
{
	if (args->argc != 1)
		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");

	pmemobj_tx_commit();
	pocli_printf(ctx, "%s\n", args->argv[0]);

	return POCLI_RET_OK;
}
Esempio n. 10
0
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");
}
Esempio n. 11
0
/*
 * pocli_pmemobj_tx_abort -- pmemobj_tx_abort() command
 */
static enum pocli_ret
pocli_pmemobj_tx_abort(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");
	int err;
	int count = sscanf(args->argv[1], "%d", &err);
	if (count != 1)
		return POCLI_ERR_PARS;

	ctx->tx_aborted = true;
	free(args);
	pmemobj_tx_abort(err);
	pocli_printf(ctx, "pmemobj_tx_abort: %d", err);

	return POCLI_RET_OK;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
/*
 * parse_stage -- return proper string variable referring to transaction state
 */
static const char *
parse_stage()
{
	int st = pmemobj_tx_stage();
	const char *stage = "";
	switch (st) {
		case TX_STAGE_NONE:
			stage = "TX_STAGE_NONE";
		break;
		case TX_STAGE_WORK:
			stage = "TX_STAGE_WORK";
		break;
		case TX_STAGE_ONCOMMIT:
			stage = "TX_STAGE_ONCOMMIT";
		break;
		case TX_STAGE_ONABORT:
			stage = "TX_STAGE_ONABORT";
		break;
		case TX_STAGE_FINALLY:
			stage = "TX_STAGE_FINALLY";
		break;
	}
	return stage;
}
Esempio n. 14
0
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);
}