Exemplo n.º 1
0
/** check if OK, free struct */
void 
checklock_destroy(enum check_lock_type type, struct checked_lock** lock,
        const char* func, const char* file, int line)
{
	const size_t contention_interest = 1; /* promille contented locks */
	struct checked_lock* e;
	if(!lock) 
		return;
	e = *lock;
	if(!e)
		return;
	checktype(type, e, func, file, line);

	/* check if delete is OK */
	acquire_locklock(e, func, file, line);
	if(e->hold_count != 0)
		lock_error(e, func, file, line, "delete while locked.");
	if(e->wait_count != 0)
		lock_error(e, func, file, line, "delete while waited on.");
	prot_check(e, func, file, line);
	*lock = NULL; /* use after free will fail */
	LOCKRET(pthread_mutex_unlock(&e->lock));

	/* contention, look at fraction in trouble. */
	if(e->history_count > 1 &&
	   1000*e->contention_count/e->history_count > contention_interest) {
		log_info("lock created %s %s %d has contention %u of %u (%d%%)",
			e->create_func, e->create_file, e->create_line,
			(unsigned int)e->contention_count, 
			(unsigned int)e->history_count,
			(int)(100*e->contention_count/e->history_count));
	}

	/* delete it */
	LOCKRET(pthread_mutex_destroy(&e->lock));
	prot_clear(e);
	/* since nobody holds the lock - see check above, no need to unlink 
	 * from the thread-held locks list. */
	switch(e->type) {
		case check_lock_mutex:
			LOCKRET(pthread_mutex_destroy(&e->u.mutex));
			break;
		case check_lock_spinlock:
			LOCKRET(pthread_spin_destroy(&e->u.spinlock));
			break;
		case check_lock_rwlock:
			LOCKRET(pthread_rwlock_destroy(&e->u.rwlock));
			break;
		default:
			log_assert(0);
	}
	memset(e, 0, sizeof(struct checked_lock));
	free(e);
}
Exemplo n.º 2
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.");
		}
Exemplo n.º 3
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.");
	}
Exemplo n.º 4
0
/** 
 * Obtain lock on debug lock structure. This could be a deadlock by the caller.
 * The debug code itself does not deadlock. Anyway, check with timeouts. 
 * @param lock: on what to acquire lock.
 * @param func: user level caller identification.
 * @param file: user level caller identification.
 * @param line: user level caller identification.
 */
static void
acquire_locklock(struct checked_lock* lock, 
	const char* func, const char* file, int line)
{
	struct timespec to;
	int err;
	int contend = 0;
	/* first try; inc contention counter if not immediately */
	if((err = pthread_mutex_trylock(&lock->lock))) {
		if(err==EBUSY)
			contend++;
		else fatal_exit("error in mutex_trylock: %s", strerror(err));
	}
	if(!err)
		return; /* immediate success */
	to.tv_sec = time(NULL) + CHECK_LOCK_TIMEOUT;
	to.tv_nsec = 0;
	err = pthread_mutex_timedlock(&lock->lock, &to);
	if(err) {
		log_err("in acquiring locklock: %s", strerror(err));
		lock_error(lock, func, file, line, "acquire locklock");
	}
	/* since we hold the lock, we can edit the contention_count */
	lock->contention_count += contend;
}
Exemplo n.º 5
0
    bool timed_wait(L& lock, const xtime& xt)
    {
        if (!lock)
            throw lock_error();

        return do_timed_wait(lock.m_mutex, xt);
    }
Exemplo n.º 6
0
    void wait(L& lock)
    {
        if (!lock)
            throw lock_error();

        do_wait(lock.m_mutex);
    }
Exemplo n.º 7
0
Arquivo: mutex.hpp Projeto: Yalir/Awl
 void lock()
 {
     int const res=pthread_mutex_lock(&m);
     if(res)
     {
         boost::throw_exception(lock_error(res));
     }
 }
Exemplo n.º 8
0
    void wait(L& lock, Pr pred)
    {
        if (!lock)
            throw lock_error();

        while (!pred())
            do_wait(lock.m_mutex);
    }
Exemplo n.º 9
0
	void wait( unique_lock< mutex > & lk, Pred pred)
	{
		if ( ! lk)
			throw lock_error();

		while ( ! pred() )
			wait( * lk.mutex() );
	}
Exemplo n.º 10
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.");
	}
Exemplo n.º 11
0
Arquivo: mutex.hpp Projeto: Yalir/Awl
 bool try_lock()
 {
     int const res=pthread_mutex_trylock(&m);
     if(res && (res!=EBUSY))
     {
         boost::throw_exception(lock_error(res));
     }
     
     return !res;
 }
Exemplo n.º 12
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.");
	}
Exemplo n.º 13
0
/** check if type is OK for the lock given */
static void 
checktype(enum check_lock_type type, struct checked_lock* lock,
        const char* func, const char* file, int line)
{
	if(!lock) 
		fatal_exit("use of null/deleted lock at %s %s:%d", 
			func, file, line);
	if(type != lock->type) {
		lock_error(lock, func, file, line, "wrong lock type");
	}
}
Exemplo n.º 14
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);
	}
Exemplo n.º 15
0
 void lock()
 {
     int res;
     do
     {
         res = pthread_mutex_lock(&m);
     } while (res == EINTR);
     if (res)
     {
         boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
     }
 }
Exemplo n.º 16
0
    bool timed_wait(L& lock, const xtime& xt, Pr pred)
    {
        if (!lock)
            throw lock_error();

        while (!pred())
        {
            if (!do_timed_wait(lock.m_mutex, xt))
                return false;
        }

        return true;
    }
Exemplo n.º 17
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.");
		}
Exemplo n.º 18
0
/**
 * Locking routine.
 * @param type: as passed by user.
 * @param lock: as passed by user.
 * @param func: caller location.
 * @param file: caller location.
 * @param line: caller location.
 * @param tryfunc: the pthread_mutex_trylock or similar function.
 * @param timedfunc: the pthread_mutex_timedlock or similar function.
 *	Uses absolute timeout value.
 * @param arg: what to pass to tryfunc and timedlock.
 * @param exclusive: if lock must be exclusive (only one allowed).
 * @param getwr: if attempts to get writelock (or readlock) for rwlocks.
 */
static void 
checklock_lockit(enum check_lock_type type, struct checked_lock* lock,
        const char* func, const char* file, int line,
	int (*tryfunc)(void*), int (*timedfunc)(void*, struct timespec*),
	void* arg, int exclusive, int getwr)
{
	int err;
	int contend = 0;
	struct thr_check *thr = (struct thr_check*)pthread_getspecific(
		thr_debug_key);
	checktype(type, lock, func, file, line);
	if(!thr) lock_error(lock, func, file, line, "no thread info");
	
	acquire_locklock(lock, func, file, line);
	lock->wait_count ++;
	thr->waiting = lock;
	if(exclusive && lock->hold_count > 0 && lock->holder == thr) 
		lock_error(lock, func, file, line, "thread already owns lock");
	if(type==check_lock_rwlock && getwr && lock->writeholder == thr)
		lock_error(lock, func, file, line, "thread already has wrlock");
	LOCKRET(pthread_mutex_unlock(&lock->lock));

	/* first try; if busy increase contention counter */
	if((err=tryfunc(arg))) {
		struct timespec to;
		if(err != EBUSY) log_err("trylock: %s", strerror(err));
		to.tv_sec = time(NULL) + CHECK_LOCK_TIMEOUT;
		to.tv_nsec = 0;
		if((err=timedfunc(arg, &to))) {
			if(err == ETIMEDOUT)
				lock_error(lock, func, file, line, 
					"timeout possible deadlock");
			log_err("timedlock: %s", strerror(err));
		}
		contend ++;
	}
	/* got the lock */

	acquire_locklock(lock, func, file, line);
	lock->contention_count += contend;
	lock->history_count++;
	if(exclusive && lock->hold_count > 0)
		lock_error(lock, func, file, line, "got nonexclusive lock");
	if(type==check_lock_rwlock && getwr && lock->writeholder)
		lock_error(lock, func, file, line, "got nonexclusive wrlock");
	if(type==check_lock_rwlock && getwr)
		lock->writeholder = thr;
	/* check the memory areas for unauthorized changes,
	 * between last unlock time and current lock time.
	 * we check while holding the lock (threadsafe).
	 */
	if(getwr || exclusive)
		prot_check(lock, func, file, line);
	finish_acquire_lock(thr, lock, func, file, line);
	LOCKRET(pthread_mutex_unlock(&lock->lock));
}
Exemplo n.º 19
0
/** 
 * Check protected memory region. Memory compare. Exit on error. 
 * @param lock: which lock to check.
 * @param func: location we are now (when failure is detected).
 * @param file: location we are now (when failure is detected).
 * @param line: location we are now (when failure is detected).
 */
static void 
prot_check(struct checked_lock* lock,
	const char* func, const char* file, int line)
{
	struct protected_area* p = lock->prot;
	while(p) {
		if(memcmp(p->hold, p->region, p->size) != 0) {
			log_hex("memory prev", p->hold, p->size);
			log_hex("memory here", p->region, p->size);
			lock_error(lock, func, file, line, 
				"protected area modified");
		}
		p = p->next;
	}
}
Exemplo n.º 20
0
void reception::start_scan ()
{
  scan_thread = new reception_thread(frontendfd
                                     , adapter_edit->text ().toStdString ()
                                     , frontend_edit->text ().toStdString ());
  scan_thread->start ();
  QObject::connect(this, SIGNAL(lock_frequency (unsigned int)), scan_thread
                  , SLOT(lock_frequency(unsigned int)), Qt::QueuedConnection);
  QObject::connect(scan_thread, SIGNAL(lock_error_signal()), this
                  , SLOT(lock_error()), Qt::QueuedConnection);
  QObject::connect(scan_thread, SIGNAL(network_found(std::string, unsigned int)), this
                   , SLOT(network_found(std::string, unsigned int)), Qt::QueuedConnection);
  QObject::connect(scan_thread, SIGNAL(lock_end_signal()), this
                   , SLOT(lock_end()), Qt::QueuedConnection);
  Q_EMIT lock_frequency(frequencies[current_frequency_index]);
}
Exemplo n.º 21
0
void
recursive_mutex::unlock() {
    context * active_ctx = context::active();
    detail::spinlock_lock lk( wait_queue_splk_);
    if ( BOOST_UNLIKELY( active_ctx != owner_) ) {
        throw lock_error(
                std::make_error_code( std::errc::operation_not_permitted),
                "boost fiber: no  privilege to perform the operation");
    }
    if ( 0 == --count_) {
        owner_ = nullptr;
        if ( ! wait_queue_.empty() ) {
            context * ctx = & wait_queue_.front();
            wait_queue_.pop_front();
            active_ctx->schedule( ctx);
        }
    }
}
Exemplo n.º 22
0
void
recursive_timed_mutex::unlock() {
    context * ctx = context::active();
    detail::spinlock_lock lk( wait_queue_splk_);
    if ( ctx != owner_) {
        throw lock_error(
                std::make_error_code( std::errc::operation_not_permitted),
                "boost fiber: no  privilege to perform the operation");
    }
    if ( 0 == --count_) {
        if ( ! wait_queue_.empty() ) {
            context * ctx = & wait_queue_.front();
            wait_queue_.pop_front();
            owner_ = ctx;
            count_ = 1;
            context::active()->set_ready( ctx);
        } else {
            owner_ = nullptr;
            return;
        }
    }
}
Exemplo n.º 23
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");
	}
Exemplo n.º 24
0
Arquivo: sched_tc6.c Projeto: 1587/ltp
/*---------------------------------------------------------------------+
|                             lock_file ()                             |
| ==================================================================== |
|                                                                      |
| Function:  ...                                                       |
|                                                                      |
+---------------------------------------------------------------------*/
int lock_file(int fd, short lock_type, char *file)
{
	int lock_attempt = 1;
	int lock_mode;

#ifdef DEBUG
	lock_mode = F_SETLK;	/* return if lock fails        */
#else
	lock_mode = F_SETLKW;	/* set lock and use system wait */
#endif

	/* file segment locking set data type flock - information
	 * passed to system by user --
	 *   l_whence:  starting point of relative offset of file
	 *   l_start:   defines relative offset in bytes from l_whence
	 *   l_len:     number of consecutive bytes to be locked
	 */
	flock_ptr->l_whence = 0;
	flock_ptr->l_start = 0;
	flock_ptr->l_len = 0;
	flock_ptr->l_type = lock_type;

	while (fcntl(fd, lock_mode, flock_ptr) == -1) {
		if (lock_error(fd, file)) {
			sleep(NAPTIME);
			if (++lock_attempt > MAX_TRIES) {
				printf
				    ("ERROR: max lock attempts of %d reached\n",
				     MAX_TRIES);
				return (0);
			}
		} else
			return (0);
	}
	return (1);
}
 /**
  * @Requires mtx_
  */
 Stream& get() const
 {
   BOOST_THREAD_ASSERT_PRECONDITION(  mtx_, lock_error() );
   return mtx_->get(*this);
 }
Exemplo n.º 26
0
 bool try_lock()
 {
     if (m_locked) throw lock_error();
     return (m_locked = lock_ops<TimedMutex>::trylock(m_mutex));
 }
Exemplo n.º 27
0
 bool timed_lock(const xtime& xt)
 {
     if (m_locked) throw lock_error();
     return (m_locked = lock_ops<TimedMutex>::timedlock(m_mutex, xt));
 }
Exemplo n.º 28
0
 void lock()
 {
     if (m_locked) throw lock_error();
     lock_ops<Mutex>::lock(m_mutex);
     m_locked = true;
 }
Exemplo n.º 29
0
 void unlock()
 {
     if (!m_locked) throw lock_error();
     lock_ops<Mutex>::unlock(m_mutex);
     m_locked = false;
 }
Exemplo n.º 30
0
	void wait( unique_lock< mutex > & lk)
	{
		if ( ! lk)
			throw lock_error();
		wait( * lk.mutex() );
	}