diff options
Diffstat (limited to 'lib/libpthread/thread/thr_init.c')
| -rw-r--r-- | lib/libpthread/thread/thr_init.c | 62 | 
1 files changed, 47 insertions, 15 deletions
diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c index 8e13f90dc993..3cbd453d3e27 100644 --- a/lib/libpthread/thread/thr_init.c +++ b/lib/libpthread/thread/thr_init.c @@ -90,9 +90,9 @@ _thread_init(void)  	int             i;  	size_t		len;  	int		mib[2]; -	struct timeval	tv;  	struct clockinfo clockinfo;  	struct sigaction act; +	struct itimerval itimer;  	/* Check if this function has already been called: */  	if (_thread_initial) @@ -160,7 +160,7 @@ _thread_init(void)  		PANIC("Cannot get kernel write pipe flags");  	}  	/* Allocate and initialize the ready queue: */ -	else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_MAX_PRIORITY) != 0) { +	else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_LAST_PRIORITY) != 0) {  		/* Abort this application: */  		PANIC("Cannot allocate priority ready queue.");  	} @@ -171,7 +171,11 @@ _thread_init(void)  		 * abort:   		 */  		PANIC("Cannot allocate memory for initial thread"); -	} else { +	} +	/* Allocate memory for the scheduler stack: */ +	else if ((_thread_kern_sched_stack = malloc(PAGE_SIZE * 10)) == NULL) +		PANIC("Failed to allocate stack for scheduler"); +	else {  		/* Zero the global kernel thread structure: */  		memset(&_thread_kern_thread, 0, sizeof(struct pthread));  		_thread_kern_thread.flags = PTHREAD_FLAGS_PRIVATE; @@ -211,6 +215,12 @@ _thread_init(void)  		_thread_initial->attr.stackaddr_attr = _thread_initial->stack;  		_thread_initial->attr.stacksize_attr = PTHREAD_STACK_INITIAL; +		/* Setup the context for the scheduler: */ +		_setjmp(_thread_kern_sched_jb); +		SET_STACK_JB(_thread_kern_sched_jb, +		    _thread_kern_sched_stack + PAGE_SIZE*10 - sizeof(double)); +		SET_RETURN_ADDR_JB(_thread_kern_sched_jb, _thread_kern_scheduler); +  		/*  		 * Write a magic value to the thread structure  		 * to help identify valid ones: @@ -236,10 +246,19 @@ _thread_init(void)  		TAILQ_INIT(&(_thread_initial->mutexq));  		_thread_initial->priority_mutex_count = 0; -		/* Initialize last active time to now: */ -		gettimeofday(&tv, NULL); -		_thread_initial->last_active.tv_sec = tv.tv_sec; -		_thread_initial->last_active.tv_usec = tv.tv_usec; +		/* Initialize the global scheduling time: */ +		_sched_ticks = 0; +		gettimeofday((struct timeval *) &_sched_tod, NULL); + +		/* Initialize last active: */ +		_thread_initial->last_active = (long) _sched_ticks; + +		/* Initialize the initial signal frame: */ +		_thread_initial->sigframes[0] = &_thread_initial->sigframe0; +		_thread_initial->curframe = &_thread_initial->sigframe0; +		_thread_initial->curframe->ctxtype = CTX_JB_NOSIG; +		/* Set the base of the stack: */ +		_thread_initial->curframe->stackp = (unsigned long) USRSTACK;  		/* Initialise the rest of the fields: */  		_thread_initial->poll_data.nfds = 0; @@ -257,10 +276,13 @@ _thread_init(void)  		/* Initialise the global signal action structure: */  		sigfillset(&act.sa_mask);  		act.sa_handler = (void (*) ()) _thread_sig_handler; -		act.sa_flags = 0; +		act.sa_flags = SA_SIGINFO; + +		/* Clear pending signals for the process: */ +		sigemptyset(&_process_sigpending); -		/* Initialize signal handling: */ -		_thread_sig_init(); +		/* Clear the signal queue: */ +		memset(_thread_sigq, 0, sizeof(_thread_sigq));  		/* Enter a loop to get the existing signal status: */  		for (i = 1; i < NSIG; i++) { @@ -295,13 +317,19 @@ _thread_init(void)  			 */  			PANIC("Cannot initialise signal handler");  		} +		_thread_sigact[_SCHED_SIGNAL - 1].sa_flags = SA_SIGINFO; +		_thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO; +		_thread_sigact[SIGCHLD - 1].sa_flags = SA_SIGINFO; + +		/* Get the process signal mask: */ +		_thread_sys_sigprocmask(SIG_SETMASK, NULL, &_process_sigmask);  		/* Get the kernel clockrate: */  		mib[0] = CTL_KERN;  		mib[1] = KERN_CLOCKRATE;  		len = sizeof (struct clockinfo);  		if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0) -			_clock_res_nsec = clockinfo.tick * 1000; +			_clock_res_usec = clockinfo.tick;  		/* Get the table size: */  		if ((_thread_dtablesize = getdtablesize()) < 0) { @@ -346,6 +374,14 @@ _thread_init(void)  					PANIC("Cannot initialize stdio file "  					    "descriptor table entry");  			} + +			/* Install the scheduling timer: */ +			itimer.it_interval.tv_sec = 0; +			itimer.it_interval.tv_usec = _clock_res_usec; +			itimer.it_value = itimer.it_interval; +			if (setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL) != 0) +				PANIC("Cannot set interval timer"); +  		}  	} @@ -362,10 +398,6 @@ _thread_init(void)  	if (pthread_mutex_init(&_gc_mutex,NULL) != 0 ||  	    pthread_cond_init(&_gc_cond,NULL) != 0)  		PANIC("Failed to initialise garbage collector mutex or condvar"); - -	gettimeofday(&kern_inc_prio_time, NULL); - -	return;  }  /*  | 
