diff options
Diffstat (limited to 'lib/libkse/thread/thr_kern.c')
| -rw-r--r-- | lib/libkse/thread/thr_kern.c | 231 | 
1 files changed, 230 insertions, 1 deletions
| diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index 35e8e29b9711..c6759cfe3b3d 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -250,18 +250,30 @@ __asm__("fnsave %0": :"m"(*fdata));  			    pthread->state == PS_FDW_WAIT ||  			    pthread->state == PS_SELECT_WAIT) {  				/* Check if this thread is to wait forever: */ +#if	defined(__FreeBSD__)  				if (pthread->wakeup_time.ts_sec == -1) { +#else +				if (pthread->wakeup_time.tv_sec == -1) { +#endif  				}  				/*  				 * Check if this thread is to wakeup  				 * immediately or if it is past its wakeup  				 * time:   				 */ +#if	defined(__FreeBSD__)  				else if ((pthread->wakeup_time.ts_sec == 0 &&  					pthread->wakeup_time.ts_nsec == 0) ||  					 (ts.ts_sec > pthread->wakeup_time.ts_sec) ||  					 ((ts.ts_sec == pthread->wakeup_time.ts_sec) &&  					  (ts.ts_nsec >= pthread->wakeup_time.ts_nsec))) { +#else +				else if ((pthread->wakeup_time.tv_sec == 0 && +					pthread->wakeup_time.tv_nsec == 0) || +					 (ts.tv_sec > pthread->wakeup_time.tv_sec) || +					 ((ts.tv_sec == pthread->wakeup_time.tv_sec) && +					  (ts.tv_nsec >= pthread->wakeup_time.tv_nsec))) { +#endif  					/*  					 * Check if this thread is waiting on  					 * select:  @@ -364,9 +376,48 @@ __asm__("fnsave %0": :"m"(*fdata));  		}  		/*  		 * Enter a loop to look for the first thread of the highest -		 * priority:  +		 * priority that is ready to run:   		 */  		for (pthread = _thread_link_list; pthread != NULL; pthread = pthread->nxt) { +			/* Check if in single-threaded mode: */ +			if (_thread_single != NULL) { +				/* +				 * Check if the current thread is +				 * the thread for which single-threaded +				 * mode is enabled: +				 */ +				if (pthread == _thread_single) { +					/* +					 * This thread is allowed +					 * to run. +					 */ +				} else { +					/* +					 * Walk up the signal handler +                                         * parent thread tree to see +					 * if the current thread is +					 * descended from the thread +					 * for which single-threaded +					 * mode is enabled. +					 */ +					pthread_nxt = pthread; +					while(pthread_nxt != NULL && +						pthread_nxt != _thread_single) { +						pthread_nxt = pthread->parent_thread; +					} +					/* +					 * Check if the current +					 * thread is not descended +					 * from the thread for which +					 * single-threaded mode is +					 * enabled. +					 */ +					if (pthread_nxt == NULL) +						/* Ignore this thread. */ +						continue; +				} +			} +  			/* Check if the current thread is unable to run: */  			if (pthread->state != PS_RUNNING) {  			} @@ -392,6 +443,45 @@ __asm__("fnsave %0": :"m"(*fdata));  		 * least recently.   		 */  		for (pthread = _thread_link_list; pthread != NULL; pthread = pthread->nxt) { +			/* Check if in single-threaded mode: */ +			if (_thread_single != NULL) { +				/* +				 * Check if the current thread is +				 * the thread for which single-threaded +				 * mode is enabled: +				 */ +				if (pthread == _thread_single) { +					/* +					 * This thread is allowed +					 * to run. +					 */ +				} else { +					/* +					 * Walk up the signal handler +                                         * parent thread tree to see +					 * if the current thread is +					 * descended from the thread +					 * for which single-threaded +					 * mode is enabled. +					 */ +					pthread_nxt = pthread; +					while(pthread_nxt != NULL && +						pthread_nxt != _thread_single) { +						pthread_nxt = pthread->parent_thread; +					} +					/* +					 * Check if the current +					 * thread is not descended +					 * from the thread for which +					 * single-threaded mode is +					 * enabled. +					 */ +					if (pthread_nxt == NULL) +						/* Ignore this thread. */ +						continue; +				} +			} +  			/* Check if the current thread is unable to run: */  			if (pthread->state != PS_RUNNING) {  				/* Ignore threads that are not ready to run. */ @@ -446,6 +536,45 @@ __asm__("fnsave %0": :"m"(*fdata));  			 * priority. 3. Became inactive least recently.   			 */  			for (pthread = _thread_link_list; pthread != NULL; pthread = pthread->nxt) { +				/* Check if in single-threaded mode: */ +				if (_thread_single != NULL) { +					/* +					 * Check if the current thread is +					 * the thread for which single-threaded +					 * mode is enabled: +					 */ +					if (pthread == _thread_single) { +						/* +						 * This thread is allowed +						 * to run. +						 */ +					} else { +						/* +						 * Walk up the signal handler +						 * parent thread tree to see +						 * if the current thread is +						 * descended from the thread +						 * for which single-threaded +						 * mode is enabled. +						 */ +						pthread_nxt = pthread; +						while(pthread_nxt != NULL && +							pthread_nxt != _thread_single) { +							pthread_nxt = pthread->parent_thread; +						} +						/* +						 * Check if the current +						 * thread is not descended +						 * from the thread for which +						 * single-threaded mode is +						 * enabled. +						 */ +						if (pthread_nxt == NULL) +							/* Ignore this thread. */ +							continue; +					} +				} +  				/*  				 * Check if the current thread is unable to  				 * run:  @@ -565,22 +694,37 @@ __asm__("fnsave %0": :"m"(*fdata));  						 * Check if this thread is to  						 * wait forever:   						 */ +#if	defined(__FreeBSD__)  						if (pthread->wakeup_time.ts_sec == -1) { +#else +						if (pthread->wakeup_time.tv_sec == -1) { +#endif  						}  						/*  						 * Check if this thread is to  						 * wakeup immediately:   						 */ +#if	defined(__FreeBSD__)  						else if (pthread->wakeup_time.ts_sec == 0 &&  							 pthread->wakeup_time.ts_nsec == 0) { +#else +						else if (pthread->wakeup_time.tv_sec == 0 && +							 pthread->wakeup_time.tv_nsec == 0) { +#endif  						}  						/*  						 * Check if the current time  						 * is after the wakeup time:   						 */ +#if	defined(__FreeBSD__)  						else if ((ts.ts_sec > pthread->wakeup_time.ts_sec) ||  							 ((ts.ts_sec == pthread->wakeup_time.ts_sec) &&  							  (ts.ts_nsec > pthread->wakeup_time.ts_nsec))) { +#else +						else if ((ts.tv_sec > pthread->wakeup_time.tv_sec) || +							 ((ts.tv_sec == pthread->wakeup_time.tv_sec) && +							  (ts.tv_nsec > pthread->wakeup_time.tv_nsec))) { +#endif  						} else {  							/*  							 * Calculate the time @@ -589,16 +733,26 @@ __asm__("fnsave %0": :"m"(*fdata));  							 * for the clock  							 * resolution:   							 */ +#if	defined(__FreeBSD__)  							ts1.ts_sec = pthread->wakeup_time.ts_sec - ts.ts_sec;  							ts1.ts_nsec = pthread->wakeup_time.ts_nsec - ts.ts_nsec +  								CLOCK_RES_NSEC; +#else +							ts1.tv_sec = pthread->wakeup_time.tv_sec - ts.tv_sec; +							ts1.tv_nsec = pthread->wakeup_time.tv_nsec - ts.tv_nsec + +								CLOCK_RES_NSEC; +#endif  							/*  							 * Check for  							 * underflow of the  							 * nanosecond field:   							 */ +#if	defined(__FreeBSD__)  							if (ts1.ts_nsec < 0) { +#else +							if (ts1.tv_nsec < 0) { +#endif  								/*  								 * Allow for  								 * the @@ -607,15 +761,24 @@ __asm__("fnsave %0": :"m"(*fdata));  								 * nanosecond  								 * field:   								 */ +#if	defined(__FreeBSD__)  								ts1.ts_sec--;  								ts1.ts_nsec += 1000000000; +#else +								ts1.tv_sec--; +								ts1.tv_nsec += 1000000000; +#endif  							}  							/*  							 * Check for overflow  							 * of the nanosecond  							 * field:   							 */ +#if	defined(__FreeBSD__)  							if (ts1.ts_nsec >= 1000000000) { +#else +							if (ts1.tv_nsec >= 1000000000) { +#endif  								/*  								 * Allow for  								 * the @@ -624,8 +787,13 @@ __asm__("fnsave %0": :"m"(*fdata));  								 * nanosecond  								 * field:   								 */ +#if	defined(__FreeBSD__)  								ts1.ts_sec++;  								ts1.ts_nsec -= 1000000000; +#else +								ts1.tv_sec++; +								ts1.tv_nsec -= 1000000000; +#endif  							}  							/*  							 * Convert the @@ -1100,11 +1268,20 @@ _thread_kern_select(int wait_reqd)  		 */  		if (wait_reqd && settimeout) {  			/* Check if this thread wants to wait forever: */ +#if	defined(__FreeBSD__)  			if (pthread->wakeup_time.ts_sec == -1) { +#else +			if (pthread->wakeup_time.tv_sec == -1) { +#endif  			}  			/* Check if this thread doesn't want to wait at all: */ +#if	defined(__FreeBSD__)  			else if (pthread->wakeup_time.ts_sec == 0 &&  				 pthread->wakeup_time.ts_nsec == 0) { +#else +			else if (pthread->wakeup_time.tv_sec == 0 && +				 pthread->wakeup_time.tv_nsec == 0) { +#endif  				/* Override the caller's request to wait: */  				wait_reqd = 0;  			} else { @@ -1112,33 +1289,57 @@ _thread_kern_select(int wait_reqd)  				 * Calculate the time until this thread is  				 * ready, allowing for the clock resolution:   				 */ +#if	defined(__FreeBSD__)  				ts1.ts_sec = pthread->wakeup_time.ts_sec - ts.ts_sec;  				ts1.ts_nsec = pthread->wakeup_time.ts_nsec - ts.ts_nsec +  					CLOCK_RES_NSEC; +#else +				ts1.tv_sec = pthread->wakeup_time.tv_sec - ts.tv_sec; +				ts1.tv_nsec = pthread->wakeup_time.tv_nsec - ts.tv_nsec + +					CLOCK_RES_NSEC; +#endif  				/*  				 * Check for underflow of the nanosecond  				 * field:   				 */ +#if	defined(__FreeBSD__)  				if (ts1.ts_nsec < 0) { +#else +				if (ts1.tv_nsec < 0) { +#endif  					/*  					 * Allow for the underflow of the  					 * nanosecond field:   					 */ +#if	defined(__FreeBSD__)  					ts1.ts_sec--;  					ts1.ts_nsec += 1000000000; +#else +					ts1.tv_sec--; +					ts1.tv_nsec += 1000000000; +#endif  				}  				/*  				 * Check for overflow of the nanosecond  				 * field:   				 */ +#if	defined(__FreeBSD__)  				if (ts1.ts_nsec >= 1000000000) { +#else +				if (ts1.tv_nsec >= 1000000000) { +#endif  					/*  					 * Allow for the overflow of the  					 * nanosecond field:   					 */ +#if	defined(__FreeBSD__)  					ts1.ts_sec++;  					ts1.ts_nsec -= 1000000000; +#else +					ts1.tv_sec++; +					ts1.tv_nsec -= 1000000000; +#endif  				}  				/*  				 * Convert the timespec structure to a @@ -1552,28 +1753,56 @@ _thread_kern_set_timeout(struct timespec * timeout)  		 * Set the wakeup time to something that can be recognised as  		 * different to an actual time of day:   		 */ +#if	defined(__FreeBSD__)  		_thread_run->wakeup_time.ts_sec = -1;  		_thread_run->wakeup_time.ts_nsec = -1; +#else +		_thread_run->wakeup_time.tv_sec = -1; +		_thread_run->wakeup_time.tv_nsec = -1; +#endif  	}  	/* Check if no waiting is required: */ +#if	defined(__FreeBSD__)  	else if (timeout->ts_sec == 0 && timeout->ts_nsec == 0) { +#else +	else if (timeout->tv_sec == 0 && timeout->tv_nsec == 0) { +#endif  		/* Set the wake up time to 'immediately': */ +#if	defined(__FreeBSD__)  		_thread_run->wakeup_time.ts_sec = 0;  		_thread_run->wakeup_time.ts_nsec = 0; +#else +		_thread_run->wakeup_time.tv_sec = 0; +		_thread_run->wakeup_time.tv_nsec = 0; +#endif  	} else {  		/* Get the current time: */  		gettimeofday(&tv, NULL);  		TIMEVAL_TO_TIMESPEC(&tv, ¤t_time);  		/* Calculate the time for the current thread to wake up: */ +#if	defined(__FreeBSD__)  		_thread_run->wakeup_time.ts_sec = current_time.ts_sec + timeout->ts_sec;  		_thread_run->wakeup_time.ts_nsec = current_time.ts_nsec + timeout->ts_nsec; +#else +		_thread_run->wakeup_time.tv_sec = current_time.tv_sec + timeout->tv_sec; +		_thread_run->wakeup_time.tv_nsec = current_time.tv_nsec + timeout->tv_nsec; +#endif  		/* Check if the nanosecond field needs to wrap: */ +#if	defined(__FreeBSD__)  		if (_thread_run->wakeup_time.ts_nsec >= 1000000000) { +#else +		if (_thread_run->wakeup_time.tv_nsec >= 1000000000) { +#endif  			/* Wrap the nanosecond field: */ +#if	defined(__FreeBSD__)  			_thread_run->wakeup_time.ts_sec += 1;  			_thread_run->wakeup_time.ts_nsec -= 1000000000; +#else +			_thread_run->wakeup_time.tv_sec += 1; +			_thread_run->wakeup_time.tv_nsec -= 1000000000; +#endif  		}  	}  	return; | 
