summaryrefslogtreecommitdiffstats
path: root/lib/libkse/thread/thr_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libkse/thread/thr_kern.c')
-rw-r--r--lib/libkse/thread/thr_kern.c87
1 files changed, 45 insertions, 42 deletions
diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c
index 23f16bc..67844e1 100644
--- a/lib/libkse/thread/thr_kern.c
+++ b/lib/libkse/thread/thr_kern.c
@@ -60,7 +60,7 @@
#endif
/* Static function prototype definitions: */
-static void
+static void
thread_kern_poll(int wait_reqd);
static void
@@ -77,7 +77,7 @@ static int last_tick = 0;
* return to a previous frame.
*/
void
-_thread_kern_sched_frame(int frame)
+_thread_kern_sched_frame(struct pthread_signal_frame *psf)
{
/*
* Flag the pthread kernel as executing scheduler code
@@ -86,13 +86,8 @@ _thread_kern_sched_frame(int frame)
*/
_thread_kern_in_sched = 1;
- /* Return to the specified frame: */
- _thread_run->curframe = _thread_run->sigframes[frame];
- _thread_run->sigframe_count = frame;
-
- if (_thread_run->sigframe_count == 0)
- /* Restore the threads priority: */
- _thread_run->active_priority &= ~PTHREAD_SIGNAL_PRIORITY;
+ /* Restore the signal frame: */
+ _thread_sigframe_restore(_thread_run, psf);
/* Switch to the thread scheduler: */
___longjmp(_thread_kern_sched_jb, 1);
@@ -127,16 +122,16 @@ _thread_kern_sched(ucontext_t *scp)
_thread_kern_scheduler();
} else {
/* Save the state of the current thread: */
- if (_setjmp(_thread_run->curframe->ctx.jb) == 0) {
+ if (_setjmp(_thread_run->ctx.jb) == 0) {
/* Flag the jump buffer was the last state saved: */
- _thread_run->curframe->ctxtype = CTX_JB_NOSIG;
- _thread_run->curframe->longjmp_val = 1;
+ _thread_run->ctxtype = CTX_JB_NOSIG;
+ _thread_run->longjmp_val = 1;
} else {
DBG_MSG("Returned from ___longjmp, thread %p\n",
_thread_run);
/*
* This point is reached when a longjmp() is called
- * to restore the state of a thread.
+ * to restore the state of a thread.
*
* This is the normal way out of the scheduler.
*/
@@ -147,7 +142,7 @@ _thread_kern_sched(ucontext_t *scp)
PTHREAD_AT_CANCEL_POINT) == 0) &&
((_thread_run->cancelflags &
PTHREAD_CANCEL_ASYNCHRONOUS) != 0))
- /*
+ /*
* Cancellations override signals.
*
* Stick a cancellation point at the
@@ -183,7 +178,6 @@ _thread_kern_sched_sig(void)
void
_thread_kern_scheduler(void)
{
- struct pthread_signal_frame *psf;
struct timespec ts;
struct timeval tv;
pthread_t pthread, pthread_h;
@@ -205,7 +199,7 @@ _thread_kern_scheduler(void)
* ready to run. This loop completes when there are no more threads
* in the global list or when a thread has its state restored by
* either a sigreturn (if the state was saved as a sigcontext) or a
- * longjmp (if the state was saved by a setjmp).
+ * longjmp (if the state was saved by a setjmp).
*/
while (!(TAILQ_EMPTY(&_thread_list))) {
/* Get the current time of day: */
@@ -229,7 +223,7 @@ _thread_kern_scheduler(void)
if (_thread_run->state != PS_RUNNING) {
/*
* Save the current time as the time that the
- * thread became inactive:
+ * thread became inactive:
*/
_thread_run->last_inactive = (long)current_tick;
if (_thread_run->last_inactive <
@@ -266,7 +260,7 @@ _thread_kern_scheduler(void)
/*
* States which do not depend on file descriptor I/O
- * operations or timeouts:
+ * operations or timeouts:
*/
case PS_DEADLOCK:
case PS_FDLR_WAIT:
@@ -326,10 +320,16 @@ _thread_kern_scheduler(void)
}
/*
+ * Avoid polling file descriptors if there are none
+ * waiting:
+ */
+ if (TAILQ_EMPTY(&_workq) == 0) {
+ }
+ /*
* Poll file descriptors only if a new scheduling signal
* has occurred or if we have no more runnable threads.
*/
- if (((current_tick = _sched_ticks) != last_tick) ||
+ else if (((current_tick = _sched_ticks) != last_tick) ||
((_thread_run->state != PS_RUNNING) &&
(PTHREAD_PRIOQ_FIRST() == NULL))) {
/* Unprotect the scheduling queues: */
@@ -337,7 +337,7 @@ _thread_kern_scheduler(void)
/*
* Poll file descriptors to update the state of threads
- * waiting on file I/O where data may be available:
+ * waiting on file I/O where data may be available:
*/
thread_kern_poll(0);
@@ -392,7 +392,7 @@ _thread_kern_scheduler(void)
if (add_to_prioq != 0) {
/*
* Save the current time as the time that the
- * thread became inactive:
+ * thread became inactive:
*/
current_tick = _sched_ticks;
_thread_run->last_inactive = (long)current_tick;
@@ -445,7 +445,7 @@ _thread_kern_scheduler(void)
/*
* Lock the pthread kernel by changing the pointer to
* the running thread to point to the global kernel
- * thread structure:
+ * thread structure:
*/
_thread_run = &_thread_kern_thread;
DBG_MSG("No runnable threads, using kernel thread %p\n",
@@ -456,7 +456,7 @@ _thread_kern_scheduler(void)
/*
* There are no threads ready to run, so wait until
- * something happens that changes this condition:
+ * something happens that changes this condition:
*/
thread_kern_poll(1);
@@ -524,7 +524,7 @@ _thread_kern_scheduler(void)
/*
* Save the current time as the time that the thread
- * became active:
+ * became active:
*/
current_tick = _sched_ticks;
_thread_run->last_active = (long) current_tick;
@@ -532,7 +532,7 @@ _thread_kern_scheduler(void)
/*
* Check if this thread is running for the first time
* or running again after using its full time slice
- * allocation:
+ * allocation:
*/
if (_thread_run->slice_usec == -1) {
/* Reset the accumulated time slice period: */
@@ -551,36 +551,39 @@ _thread_kern_scheduler(void)
/*
* Continue the thread at its current frame:
*/
- psf = _thread_run->curframe;
- switch(psf->ctxtype) {
+ switch(_thread_run->ctxtype) {
case CTX_JB_NOSIG:
- ___longjmp(psf->ctx.jb, psf->longjmp_val);
+ ___longjmp(_thread_run->ctx.jb,
+ _thread_run->longjmp_val);
break;
case CTX_JB:
- __longjmp(psf->ctx.jb, psf->longjmp_val);
+ __longjmp(_thread_run->ctx.jb,
+ _thread_run->longjmp_val);
break;
case CTX_SJB:
- __siglongjmp(psf->ctx.sigjb, psf->longjmp_val);
+ __siglongjmp(_thread_run->ctx.sigjb,
+ _thread_run->longjmp_val);
break;
case CTX_UC:
/* XXX - Restore FP regsisters? */
- FP_RESTORE_UC(&psf->ctx.uc);
+ FP_RESTORE_UC(&_thread_run->ctx.uc);
/*
* Do a sigreturn to restart the thread that
- * was interrupted by a signal:
+ * was interrupted by a signal:
*/
_thread_kern_in_sched = 0;
#if NOT_YET
- _setcontext(&psf->ctx.uc);
+ _setcontext(&_thread_run->ctx.uc);
#else
/*
* Ensure the process signal mask is set
* correctly:
*/
- psf->ctx.uc.uc_sigmask = _process_sigmask;
- _thread_sys_sigreturn(&psf->ctx.uc);
+ _thread_run->ctx.uc.uc_sigmask =
+ _process_sigmask;
+ _thread_sys_sigreturn(&_thread_run->ctx.uc);
#endif
break;
}
@@ -800,14 +803,14 @@ thread_kern_poll(int wait_reqd)
/*
* Wait for a file descriptor to be ready for read, write, or
- * an exception, or a timeout to occur:
+ * an exception, or a timeout to occur:
*/
count = _thread_sys_poll(_thread_pfd_table, nfds, timeout_ms);
if (kern_pipe_added != 0)
/*
* Remove the pthread kernel pipe file descriptor
- * from the pollfd table:
+ * from the pollfd table:
*/
nfds = 1;
else
@@ -821,7 +824,7 @@ thread_kern_poll(int wait_reqd)
(_thread_pfd_table[0].revents & POLLRDNORM))) {
/*
* If the kernel read pipe was included in the
- * count:
+ * count:
*/
if (count > 0) {
/* Decrement the count of file descriptors: */
@@ -843,7 +846,7 @@ thread_kern_poll(int wait_reqd)
/*
* Enter a loop to look for threads waiting on file
* descriptors that are flagged as available by the
- * _poll syscall:
+ * _poll syscall:
*/
PTHREAD_WAITQ_SETACTIVE();
TAILQ_FOREACH(pthread, &_workq, qe) {
@@ -986,7 +989,7 @@ _thread_kern_set_timeout(const struct timespec * timeout)
if (timeout == NULL) {
/*
* Set the wakeup time to something that can be recognised as
- * different to an actual time of day:
+ * different to an actual time of day:
*/
_thread_run->wakeup_time.tv_sec = -1;
_thread_run->wakeup_time.tv_nsec = -1;
@@ -1042,7 +1045,7 @@ _thread_kern_sig_undefer(void)
if (_sigq_check_reqd != 0)
_thread_kern_sched(NULL);
- /*
+ /*
* Check for asynchronous cancellation before delivering any
* pending signals:
*/
@@ -1071,7 +1074,7 @@ dequeue_signals(void)
int num;
/*
- * Enter a loop to clear the pthread kernel pipe:
+ * Enter a loop to clear the pthread kernel pipe:
*/
while (((num = _thread_sys_read(_thread_kern_pipe[0], bufr,
sizeof(bufr))) > 0) || (num == -1 && errno == EINTR)) {
OpenPOWER on IntegriCloud