diff options
| author | David Xu <davidxu@FreeBSD.org> | 2003-11-29 14:22:29 +0000 | 
|---|---|---|
| committer | David Xu <davidxu@FreeBSD.org> | 2003-11-29 14:22:29 +0000 | 
| commit | 170422c2ef6a210a6e29b278d1ac9be50cdacb7c (patch) | |
| tree | 4a32c5e1d4d462b62323406ce2e8a4f54b00fc1b | |
| parent | 5a8fe60d7e677d822305195ee569a3edd0ce3b3d (diff) | |
Notes
| -rw-r--r-- | lib/libkse/thread/thr_kern.c | 115 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_private.h | 15 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_kern.c | 115 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_private.h | 15 | 
4 files changed, 62 insertions, 198 deletions
diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index 5186c524948ce..7fd8b38fe0a84 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -611,21 +611,16 @@ _thr_sched_switch(struct pthread *curthread)  void  _thr_sched_switch_unlocked(struct pthread *curthread)  { -	struct pthread *td;  	struct pthread_sigframe psf;  	struct kse *curkse; -	int ret; -	volatile int uts_once;  	volatile int resume_once = 0; -	ucontext_t uc; +	ucontext_t *uc;  	/* We're in the scheduler, 5 by 5: */  	curkse = _get_curkse();  	curthread->need_switchout = 1;	/* The thread yielded on its own. */  	curthread->critical_yield = 0;	/* No need to yield anymore. */ -	thr_accounting(curthread); -  	/* Thread can unlock the scheduler lock. */  	curthread->lock_switch = 1; @@ -638,109 +633,44 @@ _thr_sched_switch_unlocked(struct pthread *curthread)  	psf.psf_valid = 0;  	curthread->curframe = &psf; -	/* -	 * Enter the scheduler if any one of the following is true: -	 * -	 *   o The current thread is dead; it's stack needs to be -	 *     cleaned up and it can't be done while operating on -	 *     it. -	 *   o The current thread has signals pending, should -	 *     let scheduler install signal trampoline for us.  	 -	 *   o There are no runnable threads. -	 *   o The next thread to run won't unlock the scheduler -	 *     lock.  A side note: the current thread may be run -	 *     instead of the next thread in the run queue, but -	 *     we don't bother checking for that. -	 */  	if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)  		kse_sched_single(&curkse->k_kcb->kcb_kmbx); -	else if ((curthread->state == PS_DEAD) || -	    (((td = KSE_RUNQ_FIRST(curkse)) == NULL) && -	    (curthread->state != PS_RUNNING)) || -	    ((td != NULL) && (td->lock_switch == 0))) { +	else {  		curkse->k_switch = 1;  		_thread_enter_uts(curthread->tcb, curkse->k_kcb);  	} -	else { -		uts_once = 0; -		THR_GETCONTEXT(&curthread->tcb->tcb_tmbx.tm_context); -		if (uts_once == 0) { -			uts_once = 1; - -			/* Switchout the current thread. */ -			kse_switchout_thread(curkse, curthread); -			_tcb_set(curkse->k_kcb, NULL); - -		 	/* Choose another thread to run. */ -			td = KSE_RUNQ_FIRST(curkse); -			KSE_RUNQ_REMOVE(curkse, td); -			curkse->k_curthread = td; - -			/* -			 * Make sure the current thread's kse points to -			 * this kse. -			 */ -			td->kse = curkse; - -			/* -			 * Reset the time slice if this thread is running -			 * for the first time or running again after using -			 * its full time slice allocation. -			 */ -			if (td->slice_usec == -1) -				td->slice_usec = 0; - -			/* Mark the thread active. */ -			td->active = 1; - -			/* Remove the frame reference. */ -			td->curframe = NULL; - -			/* -			 * Continue the thread at its current frame. -			 * Note: TCB is set in _thread_switch -			 */ -			ret = _thread_switch(curkse->k_kcb, td->tcb, 0); -			/* This point should not be reached. */ -			if (ret != 0) -				PANIC("Bad return from _thread_switch"); -			PANIC("Thread has returned from _thread_switch"); -		} -	} +	 +	/* +	 * It is ugly we must increase critical count, because we +	 * have a frame saved, we must backout state in psf +	 * before we can process signals. + 	 */ +	curthread->critical_count += psf.psf_valid; -	if (psf.psf_valid) { -		/* -		 * It is ugly we must increase critical count, because we -		 * have a frame saved, we must backout state in psf -		 * before we can process signals. - 		 */ -		curthread->critical_count++; -	} +	/* +	 * Unlock the scheduling queue and leave the +	 * critical region. +	 */ +	/* Don't trust this after a switch! */ +	curkse = _get_curkse(); -	if (curthread->lock_switch != 0) { -		/* -		 * Unlock the scheduling queue and leave the -		 * critical region. -		 */ -		/* Don't trust this after a switch! */ -		curkse = _get_curkse(); +	curthread->lock_switch = 0; +	KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); +	_kse_critical_leave(&curthread->tcb->tcb_tmbx); -		curthread->lock_switch = 0; -		KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); -		_kse_critical_leave(&curthread->tcb->tcb_tmbx); -	}  	/*  	 * This thread is being resumed; check for cancellations.  	 */  	if ((psf.psf_valid ||  	    ((curthread->check_pending || THR_NEED_ASYNC_CANCEL(curthread))  	    && !THR_IN_CRITICAL(curthread)))) { +		uc = alloca(sizeof(ucontext_t));  		resume_once = 0; -		THR_GETCONTEXT(&uc); +		THR_GETCONTEXT(uc);  		if (resume_once == 0) {  			resume_once = 1;  			curthread->check_pending = 0; -			thr_resume_check(curthread, &uc, &psf); +			thr_resume_check(curthread, uc, &psf);  		}  	}  	THR_ACTIVATE_LAST_LOCK(curthread); @@ -2443,6 +2373,8 @@ _thr_alloc(struct pthread *curthread)  			free(thread);  			thread = NULL;  		} else { +			thread->siginfo = calloc(_SIG_MAXSIG, +				sizeof(siginfo_t));  			/*  			 * Initialize thread locking.  			 * Lock initializing needs malloc, so don't @@ -2494,6 +2426,7 @@ thr_destroy(struct pthread *thread)  		_lockuser_destroy(&thread->lockusers[i]);  	_lock_destroy(&thread->lock);  	_tcb_dtor(thread->tcb); +	free(thread->siginfo);  	free(thread);  } diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h index d8453ffa81b0a..fc5f97e7c97ac 100644 --- a/lib/libkse/thread/thr_private.h +++ b/lib/libkse/thread/thr_private.h @@ -244,13 +244,13 @@ do {							\   */  #define	KSE_LOCK_ACQUIRE(kse, lck)					\  do {									\ -	if ((kse)->k_locklevel >= MAX_KSE_LOCKLEVEL)			\ -		PANIC("Exceeded maximum lock level");			\ -	else {								\ +	if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) {			\  		(kse)->k_locklevel++;					\  		_lock_acquire((lck),					\  		    &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0);	\  	}								\ +	else 								\ +		PANIC("Exceeded maximum lock level");			\  } while (0)  #define	KSE_LOCK_RELEASE(kse, lck)					\ @@ -665,7 +665,7 @@ struct pthread {  	 * Used for tracking delivery of signal handlers.  	 */  	struct pthread_sigframe	*curframe; -	siginfo_t		siginfo[_SIG_MAXSIG]; +	siginfo_t		*siginfo;   	/*  	 * Cancelability flags - the lower 2 bits are used by cancel @@ -846,15 +846,14 @@ do {								\  #define	THR_LOCK_ACQUIRE(thrd, lck)				\  do {								\ -	if ((thrd)->locklevel >= MAX_THR_LOCKLEVEL)		\ -		PANIC("Exceeded maximum lock level");		\ -	else {							\ +	if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) {		\  		THR_DEACTIVATE_LAST_LOCK(thrd);			\  		(thrd)->locklevel++;				\  		_lock_acquire((lck),				\  		    &(thrd)->lockusers[(thrd)->locklevel - 1],	\  		    (thrd)->active_priority);			\ -	}							\ +	} else 							\ +		PANIC("Exceeded maximum lock level");		\  } while (0)  #define	THR_LOCK_RELEASE(thrd, lck)				\ diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index 5186c524948ce..7fd8b38fe0a84 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -611,21 +611,16 @@ _thr_sched_switch(struct pthread *curthread)  void  _thr_sched_switch_unlocked(struct pthread *curthread)  { -	struct pthread *td;  	struct pthread_sigframe psf;  	struct kse *curkse; -	int ret; -	volatile int uts_once;  	volatile int resume_once = 0; -	ucontext_t uc; +	ucontext_t *uc;  	/* We're in the scheduler, 5 by 5: */  	curkse = _get_curkse();  	curthread->need_switchout = 1;	/* The thread yielded on its own. */  	curthread->critical_yield = 0;	/* No need to yield anymore. */ -	thr_accounting(curthread); -  	/* Thread can unlock the scheduler lock. */  	curthread->lock_switch = 1; @@ -638,109 +633,44 @@ _thr_sched_switch_unlocked(struct pthread *curthread)  	psf.psf_valid = 0;  	curthread->curframe = &psf; -	/* -	 * Enter the scheduler if any one of the following is true: -	 * -	 *   o The current thread is dead; it's stack needs to be -	 *     cleaned up and it can't be done while operating on -	 *     it. -	 *   o The current thread has signals pending, should -	 *     let scheduler install signal trampoline for us.  	 -	 *   o There are no runnable threads. -	 *   o The next thread to run won't unlock the scheduler -	 *     lock.  A side note: the current thread may be run -	 *     instead of the next thread in the run queue, but -	 *     we don't bother checking for that. -	 */  	if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)  		kse_sched_single(&curkse->k_kcb->kcb_kmbx); -	else if ((curthread->state == PS_DEAD) || -	    (((td = KSE_RUNQ_FIRST(curkse)) == NULL) && -	    (curthread->state != PS_RUNNING)) || -	    ((td != NULL) && (td->lock_switch == 0))) { +	else {  		curkse->k_switch = 1;  		_thread_enter_uts(curthread->tcb, curkse->k_kcb);  	} -	else { -		uts_once = 0; -		THR_GETCONTEXT(&curthread->tcb->tcb_tmbx.tm_context); -		if (uts_once == 0) { -			uts_once = 1; - -			/* Switchout the current thread. */ -			kse_switchout_thread(curkse, curthread); -			_tcb_set(curkse->k_kcb, NULL); - -		 	/* Choose another thread to run. */ -			td = KSE_RUNQ_FIRST(curkse); -			KSE_RUNQ_REMOVE(curkse, td); -			curkse->k_curthread = td; - -			/* -			 * Make sure the current thread's kse points to -			 * this kse. -			 */ -			td->kse = curkse; - -			/* -			 * Reset the time slice if this thread is running -			 * for the first time or running again after using -			 * its full time slice allocation. -			 */ -			if (td->slice_usec == -1) -				td->slice_usec = 0; - -			/* Mark the thread active. */ -			td->active = 1; - -			/* Remove the frame reference. */ -			td->curframe = NULL; - -			/* -			 * Continue the thread at its current frame. -			 * Note: TCB is set in _thread_switch -			 */ -			ret = _thread_switch(curkse->k_kcb, td->tcb, 0); -			/* This point should not be reached. */ -			if (ret != 0) -				PANIC("Bad return from _thread_switch"); -			PANIC("Thread has returned from _thread_switch"); -		} -	} +	 +	/* +	 * It is ugly we must increase critical count, because we +	 * have a frame saved, we must backout state in psf +	 * before we can process signals. + 	 */ +	curthread->critical_count += psf.psf_valid; -	if (psf.psf_valid) { -		/* -		 * It is ugly we must increase critical count, because we -		 * have a frame saved, we must backout state in psf -		 * before we can process signals. - 		 */ -		curthread->critical_count++; -	} +	/* +	 * Unlock the scheduling queue and leave the +	 * critical region. +	 */ +	/* Don't trust this after a switch! */ +	curkse = _get_curkse(); -	if (curthread->lock_switch != 0) { -		/* -		 * Unlock the scheduling queue and leave the -		 * critical region. -		 */ -		/* Don't trust this after a switch! */ -		curkse = _get_curkse(); +	curthread->lock_switch = 0; +	KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); +	_kse_critical_leave(&curthread->tcb->tcb_tmbx); -		curthread->lock_switch = 0; -		KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); -		_kse_critical_leave(&curthread->tcb->tcb_tmbx); -	}  	/*  	 * This thread is being resumed; check for cancellations.  	 */  	if ((psf.psf_valid ||  	    ((curthread->check_pending || THR_NEED_ASYNC_CANCEL(curthread))  	    && !THR_IN_CRITICAL(curthread)))) { +		uc = alloca(sizeof(ucontext_t));  		resume_once = 0; -		THR_GETCONTEXT(&uc); +		THR_GETCONTEXT(uc);  		if (resume_once == 0) {  			resume_once = 1;  			curthread->check_pending = 0; -			thr_resume_check(curthread, &uc, &psf); +			thr_resume_check(curthread, uc, &psf);  		}  	}  	THR_ACTIVATE_LAST_LOCK(curthread); @@ -2443,6 +2373,8 @@ _thr_alloc(struct pthread *curthread)  			free(thread);  			thread = NULL;  		} else { +			thread->siginfo = calloc(_SIG_MAXSIG, +				sizeof(siginfo_t));  			/*  			 * Initialize thread locking.  			 * Lock initializing needs malloc, so don't @@ -2494,6 +2426,7 @@ thr_destroy(struct pthread *thread)  		_lockuser_destroy(&thread->lockusers[i]);  	_lock_destroy(&thread->lock);  	_tcb_dtor(thread->tcb); +	free(thread->siginfo);  	free(thread);  } diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h index d8453ffa81b0a..fc5f97e7c97ac 100644 --- a/lib/libpthread/thread/thr_private.h +++ b/lib/libpthread/thread/thr_private.h @@ -244,13 +244,13 @@ do {							\   */  #define	KSE_LOCK_ACQUIRE(kse, lck)					\  do {									\ -	if ((kse)->k_locklevel >= MAX_KSE_LOCKLEVEL)			\ -		PANIC("Exceeded maximum lock level");			\ -	else {								\ +	if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) {			\  		(kse)->k_locklevel++;					\  		_lock_acquire((lck),					\  		    &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0);	\  	}								\ +	else 								\ +		PANIC("Exceeded maximum lock level");			\  } while (0)  #define	KSE_LOCK_RELEASE(kse, lck)					\ @@ -665,7 +665,7 @@ struct pthread {  	 * Used for tracking delivery of signal handlers.  	 */  	struct pthread_sigframe	*curframe; -	siginfo_t		siginfo[_SIG_MAXSIG]; +	siginfo_t		*siginfo;   	/*  	 * Cancelability flags - the lower 2 bits are used by cancel @@ -846,15 +846,14 @@ do {								\  #define	THR_LOCK_ACQUIRE(thrd, lck)				\  do {								\ -	if ((thrd)->locklevel >= MAX_THR_LOCKLEVEL)		\ -		PANIC("Exceeded maximum lock level");		\ -	else {							\ +	if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) {		\  		THR_DEACTIVATE_LAST_LOCK(thrd);			\  		(thrd)->locklevel++;				\  		_lock_acquire((lck),				\  		    &(thrd)->lockusers[(thrd)->locklevel - 1],	\  		    (thrd)->active_priority);			\ -	}							\ +	} else 							\ +		PANIC("Exceeded maximum lock level");		\  } while (0)  #define	THR_LOCK_RELEASE(thrd, lck)				\  | 
