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 8e13f90..3cbd453 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; } /* |