Exemple #1
0
static void
init_private(void)
{
	size_t len;
	int mib[2];
	char *env;

	_thr_umutex_init(&_mutex_static_lock);
	_thr_umutex_init(&_cond_static_lock);
	_thr_umutex_init(&_rwlock_static_lock);
	_thr_umutex_init(&_keytable_lock);
	_thr_urwlock_init(&_thr_atfork_lock);
	_thr_umutex_init(&_thr_event_lock);
	_thr_once_init();
	_thr_spinlock_init();
	_thr_list_init();
	_thr_wake_addr_init();
	_sleepq_init();

	/*
	 * Avoid reinitializing some things if they don't need to be,
	 * e.g. after a fork().
	 */
	if (init_once == 0) {
		/* Find the stack top */
		mib[0] = CTL_KERN;
		mib[1] = KERN_USRSTACK;
		len = sizeof (_usrstack);
		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
			PANIC("Cannot get kern.usrstack from sysctl");
		len = sizeof(_thr_is_smp);
		sysctlbyname("kern.smp.cpus", &_thr_is_smp, &len, NULL, 0);
		_thr_is_smp = (_thr_is_smp > 1);
		_thr_page_size = getpagesize();
		_thr_guard_default = _thr_page_size;
		_pthread_attr_default.guardsize_attr = _thr_guard_default;
		_pthread_attr_default.stacksize_attr = _thr_stack_default;
		env = getenv("LIBPTHREAD_SPINLOOPS");
		if (env)
			_thr_spinloops = atoi(env);
		env = getenv("LIBPTHREAD_YIELDLOOPS");
		if (env)
			_thr_yieldloops = atoi(env);
		env = getenv("LIBPTHREAD_QUEUE_FIFO");
		if (env)
			_thr_queuefifo = atoi(env);
		TAILQ_INIT(&_thr_atfork_list);
	}
	init_once = 1;
}
Exemple #2
0
int
_pthread_barrier_init(pthread_barrier_t *barrier,
		      const pthread_barrierattr_t *attr, unsigned count)
{
	pthread_barrier_t	bar;

	(void)attr;

	if (barrier == NULL || count <= 0)
		return (EINVAL);

	bar = malloc(sizeof(struct pthread_barrier));
	if (bar == NULL)
		return (ENOMEM);

	_thr_umutex_init(&bar->b_lock);
	_thr_ucond_init(&bar->b_cv);
	bar->b_cycle	= 0;
	bar->b_waiters	= 0;
	bar->b_count	= count;
	bar->b_refcount = 0;
	*barrier	= bar;

	return (0);
}
Exemple #3
0
void
_thr_spinlock_init(void)
{
	int i;

	_thr_umutex_init(&spinlock_static_lock);
	if (initialized != 0) {
		/*
		 * called after fork() to reset state of libc spin locks,
		 * it is not quite right since libc may be in inconsistent
		 * state, resetting the locks to allow current thread to be
		 * able to hold them may not help things too much, but
		 * anyway, we do our best.
		 * it is better to do pthread_atfork in libc.
		 */
		for (i = 0; i < spinlock_count; i++)
			_thr_umutex_init(&extra[i].lock);
	} else {
		initialized = 1;
	}
}
Exemple #4
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");
}
Exemple #5
0
int
_pthread_spin_init(pthread_spinlock_t *lock, int pshared)
{
	struct pthread_spinlock	*lck;
	int ret;

	if (lock == NULL || pshared != PTHREAD_PROCESS_PRIVATE)
		ret = EINVAL;
	else if ((lck = malloc(sizeof(struct pthread_spinlock))) == NULL)
		ret = ENOMEM;
	else {
		_thr_umutex_init(&lck->s_lock);
		*lock = lck;
		ret = 0;
	}

	return (ret);
}
Exemple #6
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);
}
Exemple #7
0
void
_thr_wake_addr_init(void)
{
	_thr_umutex_init(&addr_lock);
	wake_addr_head = NULL;
}
Exemple #8
0
static void
init_private(void)
{
	struct rlimit rlim;
	size_t len;
	int mib[2];
	char *env, *env_bigstack, *env_splitstack;

	_thr_umutex_init(&_mutex_static_lock);
	_thr_umutex_init(&_cond_static_lock);
	_thr_umutex_init(&_rwlock_static_lock);
	_thr_umutex_init(&_keytable_lock);
	_thr_urwlock_init(&_thr_atfork_lock);
	_thr_umutex_init(&_thr_event_lock);
	_thr_umutex_init(&_suspend_all_lock);
	_thr_spinlock_init();
	_thr_list_init();
	_thr_wake_addr_init();
	_sleepq_init();
	_single_thread = NULL;
	_suspend_all_waiters = 0;

	/*
	 * Avoid reinitializing some things if they don't need to be,
	 * e.g. after a fork().
	 */
	if (init_once == 0) {
		__thr_pshared_init();
		/* Find the stack top */
		mib[0] = CTL_KERN;
		mib[1] = KERN_USRSTACK;
		len = sizeof (_usrstack);
		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
			PANIC("Cannot get kern.usrstack from sysctl");
		env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN");
		env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN");
		if (env_bigstack != NULL || env_splitstack == NULL) {
			if (getrlimit(RLIMIT_STACK, &rlim) == -1)
				PANIC("Cannot get stack rlimit");
			_thr_stack_initial = rlim.rlim_cur;
		}
		len = sizeof(_thr_is_smp);
		sysctlbyname("kern.smp.cpus", &_thr_is_smp, &len, NULL, 0);
		_thr_is_smp = (_thr_is_smp > 1);
		_thr_page_size = getpagesize();
		_thr_guard_default = _thr_page_size;
		_pthread_attr_default.guardsize_attr = _thr_guard_default;
		_pthread_attr_default.stacksize_attr = _thr_stack_default;
		env = getenv("LIBPTHREAD_SPINLOOPS");
		if (env)
			_thr_spinloops = atoi(env);
		env = getenv("LIBPTHREAD_YIELDLOOPS");
		if (env)
			_thr_yieldloops = atoi(env);
		env = getenv("LIBPTHREAD_QUEUE_FIFO");
		if (env)
			_thr_queuefifo = atoi(env);
		TAILQ_INIT(&_thr_atfork_list);
	}
	init_once = 1;
}