Example #1
0
int
_pthread_barrier_wait(pthread_barrier_t *barrier)
{
	struct pthread *curthread = _get_curthread();
	pthread_barrier_t bar;
	int64_t cycle;
	int ret;

	if (barrier == NULL || *barrier == NULL)
		return (EINVAL);

	bar = *barrier;
	THR_UMUTEX_LOCK(curthread, &bar->b_lock);
	if (++bar->b_waiters == bar->b_count) {
		/* Current thread is lastest thread */
		bar->b_waiters = 0;
		bar->b_cycle++;
		_thr_ucond_broadcast(&bar->b_cv);
		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
		ret = PTHREAD_BARRIER_SERIAL_THREAD;
	} else {
		cycle = bar->b_cycle;
		bar->b_refcount++;
		do {
			_thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
			THR_UMUTEX_LOCK(curthread, &bar->b_lock);
			/* test cycle to avoid bogus wakeup */
		} while (cycle == bar->b_cycle);
		if (--bar->b_refcount == 0 && bar->b_destroying)
			_thr_ucond_broadcast(&bar->b_cv);
		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
		ret = 0;
	}
	return (ret);
}
Example #2
0
int
_pthread_barrier_destroy(pthread_barrier_t *barrier)
{
	pthread_barrier_t bar;
	struct pthread *curthread;
	int pshared;

	if (barrier == NULL || *barrier == NULL)
		return (EINVAL);

	if (*barrier == THR_PSHARED_PTR) {
		bar = __thr_pshared_offpage(barrier, 0);
		if (bar == NULL) {
			*barrier = NULL;
			return (0);
		}
		pshared = 1;
	} else {
		bar = *barrier;
		pshared = 0;
	}
	curthread = _get_curthread();
	THR_UMUTEX_LOCK(curthread, &bar->b_lock);
	if (bar->b_destroying) {
		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
		return (EBUSY);
	}
	bar->b_destroying = 1;
	do {
		if (bar->b_waiters > 0) {
			bar->b_destroying = 0;
			THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
			return (EBUSY);
		}
		if (bar->b_refcount != 0) {
			_thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
			THR_UMUTEX_LOCK(curthread, &bar->b_lock);
		} else
			break;
	} while (1);
	bar->b_destroying = 0;
	THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);

	*barrier = NULL;
	if (pshared)
		__thr_pshared_destroy(barrier);
	else
		free(bar);
	return (0);
}
Example #3
0
void
_spinunlock(spinlock_t *lck)
{
	struct spinlock_extra	*_extra;

	_extra = (struct spinlock_extra *)lck->fname;
	THR_UMUTEX_UNLOCK(_get_curthread(), &_extra->lock);
}
Example #4
0
void
__thr_spinunlock(spinlock_t *lck)
{
	struct spinlock_extra	*_extra;

	_extra = lck->thr_extra;
	THR_UMUTEX_UNLOCK(_get_curthread(), &_extra->lock);
}
Example #5
0
int
_pthread_spin_unlock(pthread_spinlock_t *lock)
{
	struct pthread_spinlock	*lck;

	if (lock == NULL)
		return (EINVAL);
	lck = *lock == THR_PSHARED_PTR ? __thr_pshared_offpage(lock, 0) : *lock;
	if (lck == NULL)
		return (EINVAL);
	return (THR_UMUTEX_UNLOCK(_get_curthread(), &lck->s_lock));
}
Example #6
0
void
_thr_report_death(struct pthread *curthread)
{
	curthread->event_buf.event = TD_DEATH;
	curthread->event_buf.th_p = (uintptr_t)curthread;
	curthread->event_buf.data = 0;
	THR_UMUTEX_LOCK(curthread, &_thr_event_lock);
	_thread_last_event = curthread;
	_thread_bp_death();
	_thread_last_event = NULL;
	THR_UMUTEX_UNLOCK(curthread, &_thr_event_lock);
}
Example #7
0
void
_thr_report_creation(struct pthread *curthread, struct pthread *newthread)
{
	curthread->event_buf.event = TD_CREATE;
	curthread->event_buf.th_p = (uintptr_t)newthread;
	curthread->event_buf.data = 0;
	THR_UMUTEX_LOCK(curthread, &_thr_event_lock);
	_thread_last_event = curthread;
	_thread_bp_create();
	_thread_last_event = NULL;
	THR_UMUTEX_UNLOCK(curthread, &_thr_event_lock);
}
Example #8
0
int
_pthread_spin_unlock(pthread_spinlock_t *lock)
{
	struct pthread *curthread = _get_curthread();
	struct pthread_spinlock	*lck;
	int ret;

	if (lock == NULL || (lck = *lock) == NULL)
		ret = EINVAL;
	else {
		ret = THR_UMUTEX_UNLOCK(curthread, &lck->s_lock);
	}
	return (ret);
}
Example #9
0
int
_pthread_barrier_destroy(pthread_barrier_t *barrier)
{
	pthread_barrier_t	bar;
	struct pthread		*curthread;

	if (barrier == NULL || *barrier == NULL)
		return (EINVAL);

	curthread = _get_curthread();
	bar = *barrier;
	THR_UMUTEX_LOCK(curthread, &bar->b_lock);
	if (bar->b_destroying) {
		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
		return (EBUSY);
	}
	bar->b_destroying = 1;
	do {
		if (bar->b_waiters > 0) {
			bar->b_destroying = 0;
			THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
			return (EBUSY);
		}
		if (bar->b_refcount != 0) {
			_thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
			THR_UMUTEX_LOCK(curthread, &bar->b_lock);
		} else
			break;
	} while (1);
	bar->b_destroying = 0;
	THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);

	*barrier = NULL;
	free(bar);
	return (0);
}
Example #10
0
static void
init_spinlock(spinlock_t *lck)
{
	struct pthread *curthread = _get_curthread();

	THR_UMUTEX_LOCK(curthread, &spinlock_static_lock);
	if ((lck->thr_extra == NULL) && (spinlock_count < MAX_SPINLOCKS)) {
		lck->thr_extra = &extra[spinlock_count];
		_thr_umutex_init(&extra[spinlock_count].lock);
		extra[spinlock_count].owner = lck;
		spinlock_count++;
	}
	THR_UMUTEX_UNLOCK(curthread, &spinlock_static_lock);
	if (lck->thr_extra == NULL)
		PANIC("Warning: exceeded max spinlocks");
}