Esempio n. 1
0
static int
cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
{
	struct pthread_cond *cvp;
	const struct pthread_cond_attr *cattr;
	int pshared;

	cattr = cond_attr != NULL ? *cond_attr : NULL;
	if (cattr == NULL || cattr->c_pshared == PTHREAD_PROCESS_PRIVATE) {
		pshared = 0;
		cvp = calloc(1, sizeof(struct pthread_cond));
		if (cvp == NULL)
			return (ENOMEM);
	} else {
		pshared = 1;
		cvp = __thr_pshared_offpage(cond, 1);
		if (cvp == NULL)
			return (EFAULT);
	}

	/*
	 * Initialise the condition variable structure:
	 */
	cond_init_body(cvp, cattr);
	*cond = pshared ? THR_PSHARED_PTR : cvp;
	return (0);
}
Esempio n. 2
0
int
_pthread_spin_lock(pthread_spinlock_t *lock)
{
	struct pthread *curthread;
	struct pthread_spinlock	*lck;
	int count;

	if (lock == NULL)
		return (EINVAL);
	lck = *lock == THR_PSHARED_PTR ? __thr_pshared_offpage(lock, 0) : *lock;
	if (lck == NULL)
		return (EINVAL);

	curthread = _get_curthread();
	count = SPIN_COUNT;
	while (THR_UMUTEX_TRYLOCK(curthread, &lck->s_lock) != 0) {
		while (lck->s_lock.m_owner) {
			if (!_thr_is_smp) {
				_pthread_yield();
			} else {
				CPU_SPINWAIT;
				if (--count <= 0) {
					count = SPIN_COUNT;
					_pthread_yield();
				}
			}
		}
	}
	return (0);
}
Esempio n. 3
0
int
_pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
{
	struct pthread *curthread = _get_curthread();
	pthread_rwlock_t prwlock;
	int ret;
	int32_t state;

	if (*rwlock == THR_PSHARED_PTR) {
		prwlock = __thr_pshared_offpage(rwlock, 0);
		if (prwlock == NULL)
			return (EINVAL);
	} else {
		prwlock = *rwlock;
	}

	if (__predict_false(prwlock <= THR_RWLOCK_DESTROYED))
		return (EINVAL);

	state = prwlock->lock.rw_state;
	if (state & URWLOCK_WRITE_OWNER) {
		if (__predict_false(prwlock->owner != TID(curthread)))
			return (EPERM);
		prwlock->owner = 0;
	}

	ret = _thr_rwlock_unlock(&prwlock->lock);
	if (ret == 0 && (state & URWLOCK_WRITE_OWNER) == 0)
		curthread->rdlock_count--;

	return (ret);
}
Esempio n. 4
0
static int
cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
	const struct timespec *abstime, int cancel)
{
	struct pthread	*curthread = _get_curthread();
	struct pthread_cond *cvp;
	struct pthread_mutex *mp;
	int	error;

	CHECK_AND_INIT_COND

	if (*mutex == THR_PSHARED_PTR) {
		mp = __thr_pshared_offpage(mutex, 0);
		if (mp == NULL)
			return (EINVAL);
	} else {
		mp = *mutex;
	}

	if ((error = _mutex_owned(curthread, mp)) != 0)
		return (error);

	if (curthread->attr.sched_policy != SCHED_OTHER ||
	    (mp->m_lock.m_flags & (UMUTEX_PRIO_PROTECT|UMUTEX_PRIO_INHERIT|
		USYNC_PROCESS_SHARED)) != 0 ||
	    (cvp->__flags & USYNC_PROCESS_SHARED) != 0)
		return cond_wait_kernel(cvp, mp, abstime, cancel);
	else
		return cond_wait_user(cvp, mp, abstime, cancel);
}
Esempio n. 5
0
int
_pthread_spin_trylock(pthread_spinlock_t *lock)
{
	struct pthread_spinlock	*lck;

	if (lock == NULL || *lock == NULL)
		return (EINVAL);
	lck = *lock == THR_PSHARED_PTR ? __thr_pshared_offpage(lock, 0) : *lock;
	if (lck == NULL)
		return (EINVAL);
	return (THR_UMUTEX_TRYLOCK(_get_curthread(), &lck->s_lock));
}
Esempio n. 6
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);
}
Esempio n. 7
0
int
_pthread_spin_destroy(pthread_spinlock_t *lock)
{
	void *l;
	int ret;

	if (lock == NULL || *lock == NULL) {
		ret = EINVAL;
	} else if (*lock == THR_PSHARED_PTR) {
		l = __thr_pshared_offpage(lock, 0);
		if (l != NULL)
			__thr_pshared_destroy(l);
		ret = 0;
	} else {
		free(*lock);
		*lock = NULL;
		ret = 0;
	}
	return (ret);
}
Esempio n. 8
0
static int
rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
	pthread_rwlock_t prwlock;

	if (attr == NULL || *attr == NULL ||
	    (*attr)->pshared == PTHREAD_PROCESS_PRIVATE) {
		prwlock = calloc(1, sizeof(struct pthread_rwlock));
		if (prwlock == NULL)
			return (ENOMEM);
		*rwlock = prwlock;
	} else {
		prwlock = __thr_pshared_offpage(rwlock, 1);
		if (prwlock == NULL)
			return (EFAULT);
		prwlock->lock.rw_flags |= USYNC_PROCESS_SHARED;
		*rwlock = THR_PSHARED_PTR;
	}
	return (0);
}
Esempio n. 9
0
int
_pthread_spin_init(pthread_spinlock_t *lock, int pshared)
{
	struct pthread_spinlock	*lck;

	if (lock == NULL)
		return (EINVAL);
	if (pshared == PTHREAD_PROCESS_PRIVATE) {
		lck = malloc(sizeof(struct pthread_spinlock));
		if (lck == NULL)
			return (ENOMEM);
		*lock = lck;
	} else if (pshared == PTHREAD_PROCESS_SHARED) {
		lck = __thr_pshared_offpage(lock, 1);
		if (lck == NULL)
			return (EFAULT);
		*lock = THR_PSHARED_PTR;
	} else {
		return (EINVAL);
	}
	_thr_umutex_init(&lck->s_lock);
	return (0);
}
Esempio n. 10
0
int
_pthread_cond_destroy(pthread_cond_t *cond)
{
	struct pthread_cond *cvp;
	int error;

	error = 0;
	if (*cond == THR_PSHARED_PTR) {
		cvp = __thr_pshared_offpage(cond, 0);
		if (cvp != NULL)
			__thr_pshared_destroy(cond);
		*cond = THR_COND_DESTROYED;
	} else if ((cvp = *cond) == THR_COND_INITIALIZER) {
		/* nothing */
	} else if (cvp == THR_COND_DESTROYED) {
		error = EINVAL;
	} else {
		cvp = *cond;
		*cond = THR_COND_DESTROYED;
		free(cvp);
	}
	return (error);
}