Ejemplo n.º 1
0
	std::cv_status
	wait_until_impl(
		mutex &lock,
		const std::chrono::time_point<Clock, Duration> &abs_timeout)
	{
		PMEMobjpool *pop = pmemobj_pool_by_ptr(this);

		/* convert to my clock */
		const typename Clock::time_point their_now = Clock::now();
		const clock_type::time_point my_now = clock_type::now();
		const auto delta = abs_timeout - their_now;
		const auto my_rel = my_now + delta;

		struct timespec ts = detail::timepoint_to_timespec(my_rel);

		auto ret = pmemobj_cond_timedwait(pop, &this->pcond,
						  lock.native_handle(), &ts);

		if (ret == 0)
			return std::cv_status::no_timeout;
		else if (ret == ETIMEDOUT)
			return std::cv_status::timeout;
		else
			throw lock_error(ret, std::system_category(),
					 "Error waiting on a condition "
					 "variable.");
	}
Ejemplo n.º 2
0
/*
 * pocli_pmemobj_pool_by_ptr -- pmemobj_pool_by_ptr() command
 */
static enum pocli_ret
pocli_pmemobj_pool_by_ptr(struct pocli_ctx *ctx, struct pocli_args *args)
{
	if (args->argc != 3)
		return POCLI_ERR_ARGS;

	PMEMoid *oid;
	enum pocli_ret ret;
	uint64_t offset;


	if ((ret = pocli_args_obj(ctx, args, 1, &oid)))
		return ret;
	if ((ret = pocli_args_number(args, 2, &offset)))
		return ret;
	char *dest_p = pmemobj_direct(*oid);
	dest_p += offset;

	PMEMobjpool *pop = pmemobj_pool_by_ptr(dest_p);

	pocli_printf(ctx, "%s(%p): uuid = 0x%llx\n",
			args->argv[0], dest_p, pop->uuid_lo);

	return ret;
}
Ejemplo n.º 3
0
		/**
		 * Locks the mutex, blocks if already locked.
		 *
		 * If a different thread already locked this mutex, the calling
		 * thread will block. If the same thread tries to lock a mutex
		 * it already owns, the behavior is undefined.
		 *
		 * @throw lock_error when an error occurs, this includes all
		 * system related errors with the underlying implementation of
		 * the mutex.
		 */
		void lock()
		{
			PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
			if (int ret = pmemobj_mutex_lock(pop, &this->plock))
				throw lock_error(ret, std::system_category(),
						"Failed to lock a mutex.");
		}
Ejemplo n.º 4
0
	/**
	 * Notify and unblock one thread waiting on `*this` condition.
	 *
	 * Does nothing when no threads are waiting. It is unspecified
	 * which thread is selected for unblocking.
	 *
	 * @throw lock_error when the signal fails on the #pcond.
	 */
	void
	notify_one()
	{
		PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
		if (int ret = pmemobj_cond_signal(pop, &this->pcond))
			throw lock_error(ret, std::system_category(),
					 "Error notifying one on "
					 "a condition variable.");
	}
Ejemplo n.º 5
0
inline pool_base
pool_by_vptr(const T *that)
{
	auto pop = pmemobj_pool_by_ptr(that);
	if (!pop)
		throw pool_error("Object not in an open pool.");

	return pool_base(pop);
}
Ejemplo n.º 6
0
	/**
	 * Internal implementation of the wait call.
	 */
	void
	wait_impl(mutex &lock)
	{
		PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
		if (int ret = pmemobj_cond_wait(pop, &this->pcond,
						lock.native_handle()))
			throw lock_error(ret, std::system_category(),
					 "Error waiting on a condition "
					 "variable.");
	}
Ejemplo n.º 7
0
	/**
	 * Default constructor.
	 *
	 * @throw lock_error when the condition_variable is not from persistent
	 * memory.
	 */
	condition_variable()
	{
		PMEMobjpool *pop;
		if ((pop = pmemobj_pool_by_ptr(&pcond)) == nullptr)
			throw lock_error(
				1, std::generic_category(),
				"Persistent condition variable not from"
				" persistent memory.");

		pmemobj_cond_zero(pop, &pcond);
	}
Ejemplo n.º 8
0
		/**
		 * Tries to lock the mutex, returns regardless if the lock
		 * succeeds.
		 *
		 * Returns `true` if locking succeeded, false otherwise.  If
		 * the same thread tries to lock a mutex it already owns,
		 * the behavior is undefined.
		 *
		 * @return `true` on successful lock acquisition, `false`
		 * otherwise.
		 *
		 * @throw lock_error when an error occurs, this includes all
		 * system related errors with the underlying implementation of
		 * the mutex.
		 */
		bool try_lock()
		{
			PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
			int ret = pmemobj_mutex_trylock(pop, &this->plock);

			if (ret == 0)
				return true;
			else if (ret == EBUSY)
				return false;
			else
				throw lock_error(ret, std::system_category(),
						"Failed to lock a mutex.");
		}
Ejemplo n.º 9
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.");
}
Ejemplo n.º 10
0
	bool
	timedlock_impl(const std::chrono::time_point<Clock, Duration> &abs_time)
	{
		PMEMobjpool *pop = pmemobj_pool_by_ptr(this);

		/* convert to my clock */
		const typename Clock::time_point their_now = Clock::now();
		const clock_type::time_point my_now = clock_type::now();
		const auto delta = abs_time - their_now;
		const auto my_abs = my_now + delta;

		struct timespec ts = detail::timepoint_to_timespec(my_abs);

		auto ret = pmemobj_mutex_timedlock(pop, &this->plock, &ts);

		if (ret == 0)
			return true;
		else if (ret == ETIMEDOUT)
			return false;
		else
			throw lock_error(ret, std::system_category(),
					 "Failed to lock a mutex");
	}
Ejemplo n.º 11
0
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;

	PMEMobjpool *pops[npools];
	void *guard_after[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);

		/*
		 * Reserve a page after the pool for address checks, if it
		 * doesn't map precisely at that address - it's OK.
		 */
		guard_after[i] =
			MMAP((char *)pops[i] + PMEMOBJ_MIN_POOL, Ut_pagesize,
				PROT_READ | PROT_WRITE,
				MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

		UT_ASSERTne(guard_after[i], NULL);

		if (pops[i] == NULL)
			UT_FATAL("!pmemobj_create");
	}

	PMEMoid oids[npools];

	for (int i = 0; i < npools; ++i) {
		r = pmemobj_alloc(pops[i], &oids[i], ALLOC_SIZE, 1, NULL, NULL);
		UT_ASSERTeq(r, 0);
	}

	PMEMoid invalid = {123, 321};

	UT_ASSERTeq(pmemobj_pool_by_oid(OID_NULL), NULL);
	UT_ASSERTeq(pmemobj_pool_by_oid(invalid), NULL);

	for (int i = 0; i < npools; ++i) {
		UT_ASSERTeq(pmemobj_pool_by_oid(oids[i]), pops[i]);
	}

	UT_ASSERTeq(pmemobj_pool_by_ptr(NULL), NULL);
	UT_ASSERTeq(pmemobj_pool_by_ptr((void *)0xCBA), NULL);

	for (int i = 0; i < npools; ++i) {
		void *before_pool = (char *)pops[i] - 1;
		void *after_pool = (char *)pops[i] + PMEMOBJ_MIN_POOL + 1;
		void *edge = (char *)pops[i] + PMEMOBJ_MIN_POOL;
		void *middle = (char *)pops[i] + (PMEMOBJ_MIN_POOL / 2);
		void *in_oid = (char *)pmemobj_direct(oids[i]) +
			(ALLOC_SIZE / 2);
		UT_ASSERTeq(pmemobj_pool_by_ptr(before_pool), NULL);
		UT_ASSERTeq(pmemobj_pool_by_ptr(after_pool), NULL);
		UT_ASSERTeq(pmemobj_pool_by_ptr(edge), NULL);
		UT_ASSERTeq(pmemobj_pool_by_ptr(middle), pops[i]);
		UT_ASSERTeq(pmemobj_pool_by_ptr(in_oid), pops[i]);
		pmemobj_close(pops[i]);
		UT_ASSERTeq(pmemobj_pool_by_ptr(middle), NULL);
		UT_ASSERTeq(pmemobj_pool_by_ptr(in_oid), NULL);

		MUNMAP(guard_after[i], Ut_pagesize);
	}

	DONE(NULL);
}