diff options
Diffstat (limited to 'lib/libpthread/thread/thr_concurrency.c')
| -rw-r--r-- | lib/libpthread/thread/thr_concurrency.c | 108 | 
1 files changed, 63 insertions, 45 deletions
diff --git a/lib/libpthread/thread/thr_concurrency.c b/lib/libpthread/thread/thr_concurrency.c index a4b055f5c833..db8412100d71 100644 --- a/lib/libpthread/thread/thr_concurrency.c +++ b/lib/libpthread/thread/thr_concurrency.c @@ -28,6 +28,8 @@   */  #include <errno.h>  #include <pthread.h> +#include <sys/types.h> +#include <sys/sysctl.h>  #include "thr_private.h" @@ -52,14 +54,8 @@ _pthread_getconcurrency(void)  int  _pthread_setconcurrency(int new_level)  { -	struct pthread *curthread; -	struct kse *newkse; -	kse_critical_t crit; -	int kse_count; -	int i;  	int ret; -  	if (new_level < 0)  		ret = EINVAL;  	else if (new_level == level) @@ -71,50 +67,72 @@ _pthread_setconcurrency(int new_level)  		DBG_MSG("Can't enable threading.\n");  		ret = EAGAIN;  	} else { -		ret = 0; -		curthread = _get_curthread(); -		/* Race condition, but so what. */ -		kse_count = _kse_initial->k_kseg->kg_ksecount; -		for (i = kse_count; i < new_level; i++) { -			newkse = _kse_alloc(curthread); -			if (newkse == NULL) { -				DBG_MSG("Can't alloc new KSE.\n"); -				ret = EAGAIN; -				break; -			} -			newkse->k_kseg = _kse_initial->k_kseg; -			newkse->k_schedq = _kse_initial->k_schedq; -			newkse->k_curthread = NULL; -			crit = _kse_critical_enter(); +		ret = _thr_setconcurrency(new_level); +		if (ret == 0) +			level = new_level; +	} +	return (ret); +} + +int +_thr_setconcurrency(int new_level) +{ +	struct pthread *curthread; +	struct kse *newkse; +	kse_critical_t crit; +	int kse_count; +	int i; +	int ret; + +	ret = 0; +	curthread = _get_curthread(); +	/* Race condition, but so what. */ +	kse_count = _kse_initial->k_kseg->kg_ksecount; +	for (i = kse_count; i < new_level; i++) { +		newkse = _kse_alloc(curthread); +		if (newkse == NULL) { +			DBG_MSG("Can't alloc new KSE.\n"); +			ret = EAGAIN; +			break; +		} +		newkse->k_kseg = _kse_initial->k_kseg; +		newkse->k_schedq = _kse_initial->k_schedq; +		newkse->k_curthread = NULL; +		crit = _kse_critical_enter(); +		KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); +		TAILQ_INSERT_TAIL(&newkse->k_kseg->kg_kseq, +		    newkse, k_kgqe); +		newkse->k_kseg->kg_ksecount++; +		KSE_SCHED_UNLOCK(curthread->kse, newkse->k_kseg); +		if (kse_create(&newkse->k_mbx, 0) != 0) {  			KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); -			TAILQ_INSERT_TAIL(&newkse->k_kseg->kg_kseq, +			TAILQ_REMOVE(&newkse->k_kseg->kg_kseq,  			    newkse, k_kgqe); -			newkse->k_kseg->kg_ksecount++; +			newkse->k_kseg->kg_ksecount--;  			KSE_SCHED_UNLOCK(curthread->kse, newkse->k_kseg); -			if (_ksd_setprivate(&_kse_initial->k_ksd) != 0) { -				/* This should never happen. */ -				PANIC("pthread_setconcurrency: Unable to " -				    "set KSE specific data"); -			} -			newkse->k_flags |= KF_INITIALIZED; -			if (kse_create(&newkse->k_mbx, 0) != 0) { -				_ksd_setprivate(&curthread->kse->k_ksd); -				KSE_SCHED_LOCK(curthread->kse, newkse->k_kseg); -				TAILQ_REMOVE(&newkse->k_kseg->kg_kseq, -				    newkse, k_kgqe); -				newkse->k_kseg->kg_ksecount--; -				KSE_SCHED_UNLOCK(curthread->kse, newkse->k_kseg); -				_kse_critical_leave(crit); -				_kse_free(curthread, newkse); -				DBG_MSG("kse_create syscall failed.\n"); -				ret = EAGAIN; -				break; -			} -			_ksd_setprivate(&curthread->kse->k_ksd); +			_kse_critical_leave(crit); +			_kse_free(curthread, newkse); +			DBG_MSG("kse_create syscall failed.\n"); +			ret = EAGAIN; +			break; +		} else {  			_kse_critical_leave(crit);  		} -		if (ret == 0) -			level = new_level;  	}  	return (ret);  } + +int +_thr_setmaxconcurrency(void) +{ +	int vcpu; +	int len; +	int ret; + +	len = sizeof(vcpu); +	ret = sysctlbyname("kern.threads.virtual_cpu", &vcpu, &len, NULL, NULL); +	if (ret == 0 && vcpu > 0) +		ret = _thr_setconcurrency(vcpu); +	return (ret); +} +  | 
