summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread
diff options
context:
space:
mode:
authormini <mini@FreeBSD.org>2002-09-16 19:52:52 +0000
committermini <mini@FreeBSD.org>2002-09-16 19:52:52 +0000
commit6077cee24228562d15e285d132213eeb718439b7 (patch)
tree19954471d255ce812e704c80bd079f406bc31378 /lib/libpthread/thread
parented825a4bd02ff20716e59e0da4db93b761df2734 (diff)
downloadFreeBSD-src-6077cee24228562d15e285d132213eeb718439b7.zip
FreeBSD-src-6077cee24228562d15e285d132213eeb718439b7.tar.gz
Make libpthread KSE aware.
Reviewed by: deischen, julian Approved by: -arch
Diffstat (limited to 'lib/libpthread/thread')
-rw-r--r--lib/libpthread/thread/thr_cancel.c10
-rw-r--r--lib/libpthread/thread/thr_close.c63
-rw-r--r--lib/libpthread/thread/thr_create.c43
-rw-r--r--lib/libpthread/thread/thr_exit.c45
-rw-r--r--lib/libpthread/thread/thr_fcntl.c108
-rw-r--r--lib/libpthread/thread/thr_fork.c65
-rw-r--r--lib/libpthread/thread/thr_fsync.c14
-rw-r--r--lib/libpthread/thread/thr_info.c65
-rw-r--r--lib/libpthread/thread/thr_init.c174
-rw-r--r--lib/libpthread/thread/thr_kern.c664
-rw-r--r--lib/libpthread/thread/thr_kill.c30
-rw-r--r--lib/libpthread/thread/thr_msync.c12
-rw-r--r--lib/libpthread/thread/thr_open.c32
-rw-r--r--lib/libpthread/thread/thr_poll.c57
-rw-r--r--lib/libpthread/thread/thr_priority_queue.c4
-rw-r--r--lib/libpthread/thread/thr_private.h334
-rw-r--r--lib/libpthread/thread/thr_read.c58
-rw-r--r--lib/libpthread/thread/thr_readv.c53
-rw-r--r--lib/libpthread/thread/thr_select.c174
-rw-r--r--lib/libpthread/thread/thr_sigmask.c59
-rw-r--r--lib/libpthread/thread/thr_sigsuspend.c50
-rw-r--r--lib/libpthread/thread/thr_sigwait.c128
-rw-r--r--lib/libpthread/thread/thr_wait4.c29
-rw-r--r--lib/libpthread/thread/thr_write.c94
-rw-r--r--lib/libpthread/thread/thr_writev.c161
-rw-r--r--lib/libpthread/thread/thr_yield.c4
26 files changed, 135 insertions, 2395 deletions
diff --git a/lib/libpthread/thread/thr_cancel.c b/lib/libpthread/thread/thr_cancel.c
index 9c7fc03..e4e0216 100644
--- a/lib/libpthread/thread/thr_cancel.c
+++ b/lib/libpthread/thread/thr_cancel.c
@@ -44,20 +44,13 @@ _pthread_cancel(pthread_t pthread)
break;
case PS_SPINBLOCK:
- case PS_FDR_WAIT:
- case PS_FDW_WAIT:
- case PS_POLL_WAIT:
- case PS_SELECT_WAIT:
/* Remove these threads from the work queue: */
if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
!= 0)
PTHREAD_WORKQ_REMOVE(pthread);
/* Fall through: */
- case PS_SIGTHREAD:
case PS_SLEEP_WAIT:
case PS_WAIT_WAIT:
- case PS_SIGSUSPEND:
- case PS_SIGWAIT:
/* Interrupt and resume: */
pthread->interrupted = 1;
pthread->cancelflags |= PTHREAD_CANCELLING;
@@ -80,9 +73,6 @@ _pthread_cancel(pthread_t pthread)
case PS_SUSPENDED:
case PS_MUTEX_WAIT:
case PS_COND_WAIT:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FILE_WAIT:
/*
* Threads in these states may be in queues.
* In order to preserve queue integrity, the
diff --git a/lib/libpthread/thread/thr_close.c b/lib/libpthread/thread/thr_close.c
index c6634a5..d03961b 100644
--- a/lib/libpthread/thread/thr_close.c
+++ b/lib/libpthread/thread/thr_close.c
@@ -42,73 +42,12 @@
__weak_reference(__close, close);
int
-_close(int fd)
-{
- int flags;
- int ret;
- struct stat sb;
- struct fd_table_entry *entry;
-
- if ((fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) {
- /*
- * Don't allow silly programs to close the kernel pipe.
- */
- errno = EBADF;
- ret = -1;
- }
- /*
- * Lock the file descriptor while the file is closed and get
- * the file descriptor status:
- */
- else if (((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) &&
- ((ret = __sys_fstat(fd, &sb)) == 0)) {
- /*
- * Check if the file should be left as blocking.
- *
- * This is so that the file descriptors shared with a parent
- * process aren't left set to non-blocking if the child
- * closes them prior to exit. An example where this causes
- * problems with /bin/sh is when a child closes stdin.
- *
- * Setting a file as blocking causes problems if a threaded
- * parent accesses the file descriptor before the child exits.
- * Once the threaded parent receives a SIGCHLD then it resets
- * all of its files to non-blocking, and so it is then safe
- * to access them.
- *
- * Pipes are not set to blocking when they are closed, as
- * the parent and child will normally close the file
- * descriptor of the end of the pipe that they are not
- * using, which would then cause any reads to block
- * indefinitely.
- */
- if ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode))
- && (_thread_fd_getflags(fd) & O_NONBLOCK) == 0) {
- /* Get the current flags: */
- flags = __sys_fcntl(fd, F_GETFL, NULL);
- /* Clear the nonblocking file descriptor flag: */
- __sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
- }
-
- /* XXX: Assumes well behaved threads. */
- /* XXX: Defer real close to avoid race condition */
- entry = _thread_fd_table[fd];
- _thread_fd_table[fd] = NULL;
- free(entry);
-
- /* Close the file descriptor: */
- ret = __sys_close(fd);
- }
- return (ret);
-}
-
-int
__close(int fd)
{
int ret;
_thread_enter_cancellation_point();
- ret = _close(fd);
+ ret = __sys_close(fd);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c
index 5211cb0..0e72e96 100644
--- a/lib/libpthread/thread/thr_create.c
+++ b/lib/libpthread/thread/thr_create.c
@@ -121,27 +121,12 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
*/
new_thread->magic = PTHREAD_MAGIC;
- /* Initialise the thread for signals: */
- new_thread->sigmask = curthread->sigmask;
- new_thread->sigmask_seqno = 0;
-
- /* Initialize the signal frame: */
- new_thread->curframe = NULL;
-
- /* Initialise the jump buffer: */
- _setjmp(new_thread->ctx.jb);
-
- /*
- * Set up new stack frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * _thread_start().
- */
- SET_RETURN_ADDR_JB(new_thread->ctx.jb, _thread_start);
-
- /* The stack starts high and builds down: */
- SET_STACK_JB(new_thread->ctx.jb,
- (long)new_thread->stack + pattr->stacksize_attr
- - sizeof(double));
+ /* Initialise the machine context: */
+ getcontext(&new_thread->ctx);
+ new_thread->ctx.uc_stack.ss_sp = new_thread->stack;
+ new_thread->ctx.uc_stack.ss_size =
+ pattr->stacksize_attr;
+ makecontext(&new_thread->ctx, _thread_start, 1);
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
@@ -182,8 +167,6 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
new_thread->specific = NULL;
new_thread->cleanup = NULL;
new_thread->flags = 0;
- new_thread->poll_data.nfds = 0;
- new_thread->poll_data.fds = NULL;
new_thread->continuation = NULL;
/*
@@ -224,18 +207,8 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
/* Return a pointer to the thread structure: */
(*thread) = new_thread;
- if (f_gc != 0) {
- /* 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");
- }
-
/* Schedule the new user thread: */
- _thread_kern_sched(NULL);
+ _thread_kern_sched();
/*
* Start a garbage collector thread
@@ -257,7 +230,7 @@ _thread_start(void)
{
struct pthread *curthread = _get_curthread();
- /* We just left the scheduler via longjmp: */
+ /* We just left the scheduler via swapcontext: */
_thread_kern_in_sched = 0;
/* Run the current thread's start routine with argument: */
diff --git a/lib/libpthread/thread/thr_exit.c b/lib/libpthread/thread/thr_exit.c
index 88535d0..96d288e 100644
--- a/lib/libpthread/thread/thr_exit.c
+++ b/lib/libpthread/thread/thr_exit.c
@@ -45,42 +45,6 @@
__weak_reference(_pthread_exit, pthread_exit);
-void _exit(int status)
-{
- int flags;
- int i;
- struct itimerval itimer;
-
- /* Disable the interval timer: */
- itimer.it_interval.tv_sec = 0;
- itimer.it_interval.tv_usec = 0;
- itimer.it_value.tv_sec = 0;
- itimer.it_value.tv_usec = 0;
- setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL);
-
- /* Close the pthread kernel pipe: */
- __sys_close(_thread_kern_pipe[0]);
- __sys_close(_thread_kern_pipe[1]);
-
- /*
- * Enter a loop to set all file descriptors to blocking
- * if they were not created as non-blocking:
- */
- for (i = 0; i < _thread_dtablesize; i++) {
- /* Check if this file descriptor is in use: */
- if (_thread_fd_table[i] != NULL &&
- (_thread_fd_getflags(i) & O_NONBLOCK) == 0) {
- /* Get the current flags: */
- flags = __sys_fcntl(i, F_GETFL, NULL);
- /* Clear the nonblocking file descriptor flag: */
- __sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
- }
- }
-
- /* Call the _exit syscall: */
- __sys_exit(status);
-}
-
void
_thread_exit(char *fname, int lineno, char *string)
{
@@ -120,9 +84,6 @@ _thread_exit_cleanup(void)
* internal to the threads library, including file and fd locks,
* are not visible to the application and need to be released.
*/
- /* Unlock all owned fd locks: */
- _thread_fd_unlock_owned(curthread);
-
/* Unlock all private mutexes: */
_mutex_unlock_private(curthread);
@@ -163,12 +124,6 @@ _pthread_exit(void *status)
_thread_cleanupspecific();
}
- /* Free thread-specific poll_data structure, if allocated: */
- if (curthread->poll_data.fds != NULL) {
- free(curthread->poll_data.fds);
- curthread->poll_data.fds = NULL;
- }
-
/*
* Lock the garbage collector mutex to ensure that the garbage
* collector is not using the dead thread list.
diff --git a/lib/libpthread/thread/thr_fcntl.c b/lib/libpthread/thread/thr_fcntl.c
index 9e78d07..33a1c2f 100644
--- a/lib/libpthread/thread/thr_fcntl.c
+++ b/lib/libpthread/thread/thr_fcntl.c
@@ -40,108 +40,6 @@
__weak_reference(__fcntl, fcntl);
int
-_fcntl(int fd, int cmd,...)
-{
- int flags = 0;
- int nonblock;
- int oldfd;
- int ret;
- va_list ap;
-
- /* Lock the file descriptor: */
- if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
- /* Initialise the variable argument list: */
- va_start(ap, cmd);
-
- /* Process according to file control command type: */
- switch (cmd) {
- /* Duplicate a file descriptor: */
- case F_DUPFD:
- /*
- * Get the file descriptor that the caller wants to
- * use:
- */
- oldfd = va_arg(ap, int);
-
- /* Initialise the file descriptor table entry: */
- if ((ret = __sys_fcntl(fd, cmd, oldfd)) < 0) {
- }
- /* Initialise the file descriptor table entry: */
- else if (_thread_fd_table_init(ret) != 0) {
- /* Quietly close the file: */
- __sys_close(ret);
-
- /* Reset the file descriptor: */
- ret = -1;
- } else {
- /*
- * Save the file open flags so that they can
- * be checked later:
- */
- _thread_fd_setflags(ret,
- _thread_fd_getflags(fd));
- }
- break;
- case F_SETFD:
- flags = va_arg(ap, int);
- ret = __sys_fcntl(fd, cmd, flags);
- break;
- case F_GETFD:
- ret = __sys_fcntl(fd, cmd, 0);
- break;
- case F_GETFL:
- ret = _thread_fd_getflags(fd);
- break;
- case F_SETFL:
- /*
- * Get the file descriptor flags passed by the
- * caller:
- */
- flags = va_arg(ap, int);
-
- /*
- * Check if the user wants a non-blocking file
- * descriptor:
- */
- nonblock = flags & O_NONBLOCK;
-
- /* Set the file descriptor flags: */
- if ((ret = __sys_fcntl(fd, cmd, flags | O_NONBLOCK)) != 0) {
-
- /* Get the flags so that we behave like the kernel: */
- } else if ((flags = __sys_fcntl(fd,
- F_GETFL, 0)) == -1) {
- /* Error getting flags: */
- ret = -1;
-
- /*
- * Check if the file descriptor is non-blocking
- * with respect to the user:
- */
- } else if (nonblock)
- /* A non-blocking descriptor: */
- _thread_fd_setflags(fd, flags | O_NONBLOCK);
- else
- /* Save the flags: */
- _thread_fd_setflags(fd, flags & ~O_NONBLOCK);
- break;
- default:
- /* Might want to make va_arg use a union */
- ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
- break;
- }
-
- /* Free variable arguments: */
- va_end(ap);
-
- /* Unlock the file descriptor: */
- _FD_UNLOCK(fd, FD_RDWR);
- }
- /* Return the completion status: */
- return (ret);
-}
-
-int
__fcntl(int fd, int cmd,...)
{
int ret;
@@ -154,14 +52,14 @@ __fcntl(int fd, int cmd,...)
case F_DUPFD:
case F_SETFD:
case F_SETFL:
- ret = _fcntl(fd, cmd, va_arg(ap, int));
+ ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
break;
case F_GETFD:
case F_GETFL:
- ret = _fcntl(fd, cmd);
+ ret = __sys_fcntl(fd, cmd);
break;
default:
- ret = _fcntl(fd, cmd, va_arg(ap, void *));
+ ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
}
va_end(ap);
diff --git a/lib/libpthread/thread/thr_fork.c b/lib/libpthread/thread/thr_fork.c
index 0f17291..5bb64f7 100644
--- a/lib/libpthread/thread/thr_fork.c
+++ b/lib/libpthread/thread/thr_fork.c
@@ -63,44 +63,8 @@ _fork(void)
if ((ret = __sys_fork()) != 0) {
/* Parent process or error. Nothing to do here. */
} else {
- /* Close the pthread kernel pipe: */
- __sys_close(_thread_kern_pipe[0]);
- __sys_close(_thread_kern_pipe[1]);
-
- /* Reset signals pending for the running thread: */
- sigemptyset(&curthread->sigpend);
-
- /*
- * Create a pipe that is written to by the signal handler to
- * prevent signals being missed in calls to
- * __sys_select:
- */
- if (__sys_pipe(_thread_kern_pipe) != 0) {
- /* Cannot create pipe, so abort: */
- PANIC("Cannot create pthread kernel pipe for forked process");
- }
- /* Get the flags for the read pipe: */
- else if ((flags = __sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
- /* Abort this application: */
- abort();
- }
- /* Make the read pipe non-blocking: */
- else if (__sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
- /* Abort this application: */
- abort();
- }
- /* Get the flags for the write pipe: */
- else if ((flags = __sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
- /* Abort this application: */
- abort();
- }
- /* Make the write pipe non-blocking: */
- else if (__sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
- /* Abort this application: */
- abort();
- }
/* Reinitialize the GC mutex: */
- else if (_mutex_reinit(&_gc_mutex) != 0) {
+ if (_mutex_reinit(&_gc_mutex) != 0) {
/* Abort this application: */
PANIC("Cannot initialize GC mutex for forked process");
}
@@ -180,32 +144,8 @@ _fork(void)
/* No spinlocks yet: */
_spinblock_count = 0;
- /* Don't queue signals yet: */
- _queue_signals = 0;
-
/* Initialize the scheduling switch hook routine: */
_sched_switch_hook = NULL;
-
- /* Clear out any locks in the file descriptor table: */
- for (i = 0; i < _thread_dtablesize; i++) {
- if (_thread_fd_table[i] != NULL) {
- /* Initialise the file locks: */
- memset(&_thread_fd_table[i]->lock, 0,
- sizeof(_thread_fd_table[i]->lock));
- _thread_fd_table[i]->r_owner = NULL;
- _thread_fd_table[i]->w_owner = NULL;
- _thread_fd_table[i]->r_fname = NULL;
- _thread_fd_table[i]->w_fname = NULL;
- _thread_fd_table[i]->r_lineno = 0;;
- _thread_fd_table[i]->w_lineno = 0;;
- _thread_fd_table[i]->r_lockcount = 0;;
- _thread_fd_table[i]->w_lockcount = 0;;
-
- /* Initialise the read/write queues: */
- TAILQ_INIT(&_thread_fd_table[i]->r_queue);
- TAILQ_INIT(&_thread_fd_table[i]->w_queue);
- }
- }
}
}
@@ -236,8 +176,5 @@ free_thread_resources(struct pthread *thread)
if (thread->specific != NULL)
free(thread->specific);
- if (thread->poll_data.fds != NULL)
- free(thread->poll_data.fds);
-
free(thread);
}
diff --git a/lib/libpthread/thread/thr_fsync.c b/lib/libpthread/thread/thr_fsync.c
index 608e8b0..0ede529 100644
--- a/lib/libpthread/thread/thr_fsync.c
+++ b/lib/libpthread/thread/thr_fsync.c
@@ -38,24 +38,12 @@
__weak_reference(__fsync, fsync);
int
-_fsync(int fd)
-{
- int ret;
-
- if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) {
- ret = __sys_fsync(fd);
- _FD_UNLOCK(fd, FD_RDWR);
- }
- return (ret);
-}
-
-int
__fsync(int fd)
{
int ret;
_thread_enter_cancellation_point();
- ret = _fsync(fd);
+ ret = __sys_fsync(fd);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_info.c b/lib/libpthread/thread/thr_info.c
index 11b02f3..9ade157 100644
--- a/lib/libpthread/thread/thr_info.c
+++ b/lib/libpthread/thread/thr_info.c
@@ -56,20 +56,10 @@ struct s_thread_info {
/* Static variables: */
static const struct s_thread_info thread_info[] = {
{PS_RUNNING , "Running"},
- {PS_SIGTHREAD , "Waiting on signal thread"},
{PS_MUTEX_WAIT , "Waiting on a mutex"},
{PS_COND_WAIT , "Waiting on a condition variable"},
- {PS_FDLR_WAIT , "Waiting for a file read lock"},
- {PS_FDLW_WAIT , "Waiting for a file write lock"},
- {PS_FDR_WAIT , "Waiting for read"},
- {PS_FDW_WAIT , "Waiting for write"},
- {PS_FILE_WAIT , "Waiting for FILE lock"},
- {PS_POLL_WAIT , "Waiting on poll"},
- {PS_SELECT_WAIT , "Waiting on select"},
{PS_SLEEP_WAIT , "Sleeping"},
{PS_WAIT_WAIT , "Waiting process"},
- {PS_SIGSUSPEND , "Suspended, waiting for a signal"},
- {PS_SIGWAIT , "Waiting for a signal"},
{PS_SPINBLOCK , "Waiting for a spinlock"},
{PS_JOIN , "Waiting to join"},
{PS_SUSPENDED , "Suspended"},
@@ -169,34 +159,6 @@ _thread_dump_info(void)
}
}
- /* Output a header for file descriptors: */
- snprintf(s, sizeof(s), "\n\n=============\nFILE DESCRIPTOR "
- "TABLE (table size %d)\n\n", _thread_dtablesize);
- __sys_write(fd, s, strlen(s));
-
- /* Enter a loop to report file descriptor lock usage: */
- for (i = 0; i < _thread_dtablesize; i++) {
- /*
- * Check if memory is allocated for this file
- * descriptor:
- */
- if (_thread_fd_table[i] != NULL) {
- /* Report the file descriptor lock status: */
- snprintf(s, sizeof(s),
- "fd[%3d] read owner %p count %d [%s:%d]\n"
- " write owner %p count %d [%s:%d]\n",
- i, _thread_fd_table[i]->r_owner,
- _thread_fd_table[i]->r_lockcount,
- _thread_fd_table[i]->r_fname,
- _thread_fd_table[i]->r_lineno,
- _thread_fd_table[i]->w_owner,
- _thread_fd_table[i]->w_lockcount,
- _thread_fd_table[i]->w_fname,
- _thread_fd_table[i]->w_lineno);
- __sys_write(fd, s, strlen(s));
- }
- }
-
/* Close the dump file: */
__sys_close(fd);
}
@@ -237,33 +199,6 @@ dump_thread(int fd, pthread_t pthread, int long_version)
}
/* Process according to thread state: */
switch (pthread->state) {
- /* File descriptor read lock wait: */
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FDR_WAIT:
- case PS_FDW_WAIT:
- /* Write the lock details: */
- snprintf(s, sizeof(s), "fd %d[%s:%d]",
- pthread->data.fd.fd,
- pthread->data.fd.fname,
- pthread->data.fd.branch);
- __sys_write(fd, s, strlen(s));
- snprintf(s, sizeof(s), "owner %pr/%pw\n",
- _thread_fd_table[pthread->data.fd.fd]->r_owner,
- _thread_fd_table[pthread->data.fd.fd]->w_owner);
- __sys_write(fd, s, strlen(s));
- break;
- case PS_SIGWAIT:
- snprintf(s, sizeof(s), "sigmask (hi)");
- __sys_write(fd, s, strlen(s));
- for (i = _SIG_WORDS - 1; i >= 0; i--) {
- snprintf(s, sizeof(s), "%08x\n",
- pthread->sigmask.__bits[i]);
- __sys_write(fd, s, strlen(s));
- }
- snprintf(s, sizeof(s), "(lo)\n");
- __sys_write(fd, s, strlen(s));
- break;
/*
* Trap other states that are not explicitly
* coded to dump information:
diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c
index ba306a6..9f6a533 100644
--- a/lib/libpthread/thread/thr_init.c
+++ b/lib/libpthread/thread/thr_init.c
@@ -56,7 +56,6 @@
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
-#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@@ -163,7 +162,6 @@ _thread_init(void)
int sched_stack_size; /* Size of scheduler stack. */
struct clockinfo clockinfo;
- struct sigaction act;
_pthread_page_size = getpagesize();
_pthread_guard_default = getpagesize();
@@ -209,57 +207,9 @@ _thread_init(void)
PANIC("Can't dup2");
}
- /* Get the standard I/O flags before messing with them : */
- for (i = 0; i < 3; i++) {
- if (((_pthread_stdio_flags[i] =
- __sys_fcntl(i, F_GETFL, NULL)) == -1) &&
- (errno != EBADF))
- PANIC("Cannot get stdio flags");
- }
-
- /*
- * Create a pipe that is written to by the signal handler to prevent
- * signals being missed in calls to _select:
- */
- if (__sys_pipe(_thread_kern_pipe) != 0) {
- /* Cannot create pipe, so abort: */
- PANIC("Cannot create kernel pipe");
- }
-
- /*
- * Make sure the pipe does not get in the way of stdio:
- */
- for (i = 0; i < 2; i++) {
- if (_thread_kern_pipe[i] < 3) {
- fd = __sys_fcntl(_thread_kern_pipe[i], F_DUPFD, 3);
- if (fd == -1)
- PANIC("Cannot create kernel pipe");
- __sys_close(_thread_kern_pipe[i]);
- _thread_kern_pipe[i] = fd;
- }
- }
- /* Get the flags for the read pipe: */
- if ((flags = __sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) {
- /* Abort this application: */
- PANIC("Cannot get kernel read pipe flags");
- }
- /* Make the read pipe non-blocking: */
- else if (__sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) {
- /* Abort this application: */
- PANIC("Cannot make kernel read pipe non-blocking");
- }
- /* Get the flags for the write pipe: */
- else if ((flags = __sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) {
- /* Abort this application: */
- PANIC("Cannot get kernel write pipe flags");
- }
- /* Make the write pipe non-blocking: */
- else if (__sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) {
- /* Abort this application: */
- PANIC("Cannot get kernel write pipe flags");
- }
/* Allocate and initialize the ready queue: */
- else if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_LAST_PRIORITY) != 0) {
+ if (_pq_alloc(&_readyq, PTHREAD_MIN_PRIORITY, PTHREAD_LAST_PRIORITY) !=
+ 0) {
/* Abort this application: */
PANIC("Cannot allocate priority ready queue.");
}
@@ -312,15 +262,19 @@ _thread_init(void)
/* Set the main thread stack pointer. */
_thread_initial->stack = _usrstack - PTHREAD_STACK_INITIAL;
- /* Set the stack attributes: */
+ /* Set the stack attributes. */
_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 +
- sched_stack_size - sizeof(double));
- SET_RETURN_ADDR_JB(_thread_kern_sched_jb, _thread_kern_scheduler);
+ getcontext(&_thread_kern_sched_ctx);
+ _thread_kern_sched_ctx.uc_stack.ss_sp =
+ _thread_kern_sched_stack;
+ _thread_kern_sched_ctx.uc_stack.ss_size = sched_stack_size;
+ makecontext(&_thread_kern_sched_ctx, _thread_kern_scheduler, 1);
+
+ /* Block all signals to the scheduler's context. */
+ sigfillset(&_thread_kern_sched_ctx.uc_sigmask);
/*
* Write a magic value to the thread structure
@@ -332,6 +286,11 @@ _thread_init(void)
_thread_initial->cancelflags = PTHREAD_CANCEL_ENABLE |
PTHREAD_CANCEL_DEFERRED;
+ /* Setup the context for initial thread. */
+ getcontext(&_thread_initial->ctx);
+ _thread_kern_sched_ctx.uc_stack.ss_sp = _thread_initial->stack;
+ _thread_kern_sched_ctx.uc_stack.ss_size = PTHREAD_STACK_INITIAL;
+
/* Default the priority of the initial thread: */
_thread_initial->base_priority = PTHREAD_DEFAULT_PRIORITY;
_thread_initial->active_priority = PTHREAD_DEFAULT_PRIORITY;
@@ -357,14 +316,8 @@ _thread_init(void)
/* Initialize last active: */
_thread_initial->last_active = (long) _sched_ticks;
- /* Initialize the initial context: */
- _thread_initial->curframe = NULL;
-
/* Initialise the rest of the fields: */
- _thread_initial->poll_data.nfds = 0;
- _thread_initial->poll_data.fds = NULL;
_thread_initial->sig_defer_count = 0;
- _thread_initial->yield_on_sig_undefer = 0;
_thread_initial->specific = NULL;
_thread_initial->cleanup = NULL;
_thread_initial->flags = 0;
@@ -373,57 +326,6 @@ _thread_init(void)
TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
_set_curthread(_thread_initial);
- /* Initialise the global signal action structure: */
- sigfillset(&act.sa_mask);
- act.sa_handler = (void (*) ()) _thread_sig_handler;
- act.sa_flags = SA_SIGINFO | SA_ONSTACK;
-
- /* Clear pending signals for the process: */
- sigemptyset(&_process_sigpending);
-
- /* 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++) {
- /* Check for signals which cannot be trapped: */
- if (i == SIGKILL || i == SIGSTOP) {
- }
-
- /* Get the signal handler details: */
- else if (__sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
- /*
- * Abort this process if signal
- * initialisation fails:
- */
- PANIC("Cannot read signal handler info");
- }
-
- /* Initialize the SIG_DFL dummy handler count. */
- _thread_dfl_count[i] = 0;
- }
-
- /*
- * Install the signal handler for the most important
- * signals that the user-thread kernel needs. Actually
- * SIGINFO isn't really needed, but it is nice to have.
- */
- if (__sys_sigaction(_SCHED_SIGNAL, &act, NULL) != 0 ||
- __sys_sigaction(SIGINFO, &act, NULL) != 0 ||
- __sys_sigaction(SIGCHLD, &act, NULL) != 0) {
- /*
- * Abort this process if signal initialisation fails:
- */
- 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: */
- __sys_sigprocmask(SIG_SETMASK, NULL, &_process_sigmask);
-
/* Get the kernel clockrate: */
mib[0] = CTL_KERN;
mib[1] = KERN_CLOCKRATE;
@@ -432,50 +334,6 @@ _thread_init(void)
_clock_res_usec = clockinfo.tick > CLOCK_RES_USEC_MIN ?
clockinfo.tick : CLOCK_RES_USEC_MIN;
- /* Get the table size: */
- if ((_thread_dtablesize = getdtablesize()) < 0) {
- /*
- * Cannot get the system defined table size, so abort
- * this process.
- */
- PANIC("Cannot get dtablesize");
- }
- /* Allocate memory for the file descriptor table: */
- if ((_thread_fd_table = (struct fd_table_entry **) malloc(sizeof(struct fd_table_entry *) * _thread_dtablesize)) == NULL) {
- /* Avoid accesses to file descriptor table on exit: */
- _thread_dtablesize = 0;
-
- /*
- * Cannot allocate memory for the file descriptor
- * table, so abort this process.
- */
- PANIC("Cannot allocate memory for file descriptor table");
- }
- /* Allocate memory for the pollfd table: */
- if ((_thread_pfd_table = (struct pollfd *) malloc(sizeof(struct pollfd) * _thread_dtablesize)) == NULL) {
- /*
- * Cannot allocate memory for the file descriptor
- * table, so abort this process.
- */
- PANIC("Cannot allocate memory for pollfd table");
- } else {
- /*
- * Enter a loop to initialise the file descriptor
- * table:
- */
- for (i = 0; i < _thread_dtablesize; i++) {
- /* Initialise the file descriptor table: */
- _thread_fd_table[i] = NULL;
- }
-
- /* Initialize stdio file descriptor table entries: */
- for (i = 0; i < 3; i++) {
- if ((_thread_fd_table_init(i) != 0) &&
- (errno != EBADF))
- PANIC("Cannot initialize stdio file "
- "descriptor table entry");
- }
- }
}
/* Initialise the garbage collector mutex and condition variable. */
diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c
index 5b19690..36ed8d8 100644
--- a/lib/libpthread/thread/thr_kern.c
+++ b/lib/libpthread/thread/thr_kern.c
@@ -38,7 +38,6 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
-#include <setjmp.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/signalvar.h>
@@ -60,7 +59,7 @@
/* Static function prototype definitions: */
static void
-thread_kern_poll(int wait_reqd);
+thread_kern_idle(void);
static void
dequeue_signals(void);
@@ -70,37 +69,9 @@ thread_run_switch_hook(pthread_t thread_out, pthread_t thread_in);
/* Static variables: */
static int last_tick = 0;
-static int called_from_handler = 0;
-
-/*
- * This is called when a signal handler finishes and wants to
- * return to a previous frame.
- */
-void
-_thread_kern_sched_frame(struct pthread_signal_frame *psf)
-{
- struct pthread *curthread = _get_curthread();
-
- /*
- * Flag the pthread kernel as executing scheduler code
- * to avoid a signal from interrupting this execution and
- * corrupting the (soon-to-be) current frame.
- */
- _thread_kern_in_sched = 1;
-
- /* Restore the signal frame: */
- _thread_sigframe_restore(curthread, psf);
-
- /* The signal mask was restored; check for any pending signals: */
- curthread->check_pending = 1;
-
- /* Switch to the thread scheduler: */
- ___longjmp(_thread_kern_sched_jb, 1);
-}
-
void
-_thread_kern_sched(ucontext_t *ucp)
+_thread_kern_sched(void)
{
struct pthread *curthread = _get_curthread();
@@ -111,78 +82,40 @@ _thread_kern_sched(ucontext_t *ucp)
*/
_thread_kern_in_sched = 1;
- /* Check if this function was called from the signal handler: */
- if (ucp != NULL) {
- /* XXX - Save FP registers? */
- FP_SAVE_UC(ucp);
- called_from_handler = 1;
- DBG_MSG("Entering scheduler due to signal\n");
- }
-
- /* Save the state of the current thread: */
- if (_setjmp(curthread->ctx.jb) != 0) {
- DBG_MSG("Returned from ___longjmp, thread %p\n",
- curthread);
- /*
- * This point is reached when a longjmp() is called
- * to restore the state of a thread.
- *
- * This is the normal way out of the scheduler.
- */
- _thread_kern_in_sched = 0;
+ /* Switch into the scheduler's context. */
+ swapcontext(&curthread->ctx, &_thread_kern_sched_ctx);
+ DBG_MSG("Returned from swapcontext, thread %p\n", curthread);
- if (curthread->sig_defer_count == 0) {
- if (((curthread->cancelflags &
- PTHREAD_AT_CANCEL_POINT) == 0) &&
- ((curthread->cancelflags &
- PTHREAD_CANCEL_ASYNCHRONOUS) != 0))
- /*
- * Cancellations override signals.
- *
- * Stick a cancellation point at the
- * start of each async-cancellable
- * thread's resumption.
- *
- * We allow threads woken at cancel
- * points to do their own checks.
- */
- pthread_testcancel();
- }
-
- if (_sched_switch_hook != NULL) {
- /* Run the installed switch hook: */
- thread_run_switch_hook(_last_user_thread, curthread);
- }
- if (ucp == NULL)
- return;
- else {
- /* XXX - Restore FP registers? */
- FP_RESTORE_UC(ucp);
+ /*
+ * This point is reached when swapcontext() is called
+ * to restore the state of a thread.
+ *
+ * This is the normal way out of the scheduler.
+ */
+ _thread_kern_in_sched = 0;
+ if (curthread->sig_defer_count == 0) {
+ if (((curthread->cancelflags &
+ PTHREAD_AT_CANCEL_POINT) == 0) &&
+ ((curthread->cancelflags &
+ PTHREAD_CANCEL_ASYNCHRONOUS) != 0))
/*
- * Set the process signal mask in the context; it
- * could have changed by the handler.
+ * Stick a cancellation point at the
+ * start of each async-cancellable
+ * thread's resumption.
+ *
+ * We allow threads woken at cancel
+ * points to do their own checks.
*/
- ucp->uc_sigmask = _process_sigmask;
-
- /* Resume the interrupted thread: */
- __sys_sigreturn(ucp);
- }
+ pthread_testcancel();
}
- /* Switch to the thread scheduler: */
- ___longjmp(_thread_kern_sched_jb, 1);
-}
-
-void
-_thread_kern_sched_sig(void)
-{
- struct pthread *curthread = _get_curthread();
- curthread->check_pending = 1;
- _thread_kern_sched(NULL);
+ if (_sched_switch_hook != NULL) {
+ /* Run the installed switch hook: */
+ thread_run_switch_hook(_last_user_thread, curthread);
+ }
}
-
void
_thread_kern_scheduler(void)
{
@@ -193,48 +126,28 @@ _thread_kern_scheduler(void)
unsigned int current_tick;
int add_to_prioq;
- /* If the currently running thread is a user thread, save it: */
- if ((curthread->flags & PTHREAD_FLAGS_PRIVATE) == 0)
- _last_user_thread = curthread;
-
- if (called_from_handler != 0) {
- called_from_handler = 0;
-
- /*
- * We were called from a signal handler; restore the process
- * signal mask.
- */
- if (__sys_sigprocmask(SIG_SETMASK,
- &_process_sigmask, NULL) != 0)
- PANIC("Unable to restore process mask after signal");
- }
-
/*
* Enter a scheduling loop that finds the next thread that is
* 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).
+ * in the global list. It is interrupted each time a thread is
+ * scheduled, but will continue when we return.
*/
while (!(TAILQ_EMPTY(&_thread_list))) {
+
+ /* If the currently running thread is a user thread, save it: */
+ if ((curthread->flags & PTHREAD_FLAGS_PRIVATE) == 0)
+ _last_user_thread = curthread;
+
/* Get the current time of day: */
GET_CURRENT_TOD(tv);
TIMEVAL_TO_TIMESPEC(&tv, &ts);
current_tick = _sched_ticks;
- /*
- * Protect the scheduling queues from access by the signal
- * handler.
- */
- _queue_signals = 1;
add_to_prioq = 0;
-
if (curthread != &_thread_kern_thread) {
/*
* This thread no longer needs to yield the CPU.
*/
- curthread->yield_on_sig_undefer = 0;
-
if (curthread->state != PS_RUNNING) {
/*
* Save the current time as the time that the
@@ -278,14 +191,8 @@ _thread_kern_scheduler(void)
* operations or timeouts:
*/
case PS_DEADLOCK:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FILE_WAIT:
case PS_JOIN:
case PS_MUTEX_WAIT:
- case PS_SIGSUSPEND:
- case PS_SIGTHREAD:
- case PS_SIGWAIT:
case PS_WAIT_WAIT:
/* No timeouts for these states: */
curthread->wakeup_time.tv_sec = -1;
@@ -318,62 +225,9 @@ _thread_kern_scheduler(void)
_spinblock_count++;
/* FALLTHROUGH */
- case PS_FDR_WAIT:
- case PS_FDW_WAIT:
- case PS_POLL_WAIT:
- case PS_SELECT_WAIT:
- /* Restart the time slice: */
- curthread->slice_usec = -1;
-
- /* Insert into the waiting queue: */
- PTHREAD_WAITQ_INSERT(curthread);
-
- /* Insert into the work queue: */
- PTHREAD_WORKQ_INSERT(curthread);
- break;
- }
-
- /*
- * Are there pending signals for this thread?
- *
- * This check has to be performed after the thread
- * has been placed in the queue(s) appropriate for
- * its state. The process of adding pending signals
- * can change a threads state, which in turn will
- * attempt to add or remove the thread from any
- * scheduling queue to which it belongs.
- */
- if (curthread->check_pending != 0) {
- curthread->check_pending = 0;
- _thread_sig_check_pending(curthread);
}
}
- /*
- * 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.
- */
- else if (((current_tick = _sched_ticks) != last_tick) ||
- ((curthread->state != PS_RUNNING) &&
- (PTHREAD_PRIOQ_FIRST() == NULL))) {
- /* Unprotect the scheduling queues: */
- _queue_signals = 0;
-
- /*
- * Poll file descriptors to update the state of threads
- * waiting on file I/O where data may be available:
- */
- thread_kern_poll(0);
-
- /* Protect the scheduling queues: */
- _queue_signals = 1;
- }
last_tick = current_tick;
/*
@@ -389,25 +243,16 @@ _thread_kern_scheduler(void)
(pthread->wakeup_time.tv_sec < ts.tv_sec) ||
((pthread->wakeup_time.tv_sec == ts.tv_sec) &&
(pthread->wakeup_time.tv_nsec <= ts.tv_nsec)))) {
- switch (pthread->state) {
- case PS_POLL_WAIT:
- case PS_SELECT_WAIT:
- /* Return zero file descriptors ready: */
- pthread->data.poll_data->nfds = 0;
- /* FALLTHROUGH */
- default:
- /*
- * Remove this thread from the waiting queue
- * (and work queue if necessary) and place it
- * in the ready queue.
- */
- PTHREAD_WAITQ_CLEARACTIVE();
- if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
- PTHREAD_WORKQ_REMOVE(pthread);
- PTHREAD_NEW_STATE(pthread, PS_RUNNING);
- PTHREAD_WAITQ_SETACTIVE();
- break;
- }
+ /*
+ * Remove this thread from the waiting queue
+ * (and work queue if necessary) and place it
+ * in the ready queue.
+ */
+ PTHREAD_WAITQ_CLEARACTIVE();
+ if (pthread->flags & PTHREAD_FLAGS_IN_WORKQ)
+ PTHREAD_WORKQ_REMOVE(pthread);
+ PTHREAD_NEW_STATE(pthread, PS_RUNNING);
+ PTHREAD_WAITQ_SETACTIVE();
/*
* Flag the timeout in the thread structure:
*/
@@ -483,14 +328,11 @@ _thread_kern_scheduler(void)
DBG_MSG("No runnable threads, using kernel thread %p\n",
curthread);
- /* Unprotect the scheduling queues: */
- _queue_signals = 0;
-
/*
* There are no threads ready to run, so wait until
* something happens that changes this condition:
*/
- thread_kern_poll(1);
+ thread_kern_idle();
/*
* This process' usage will likely be very small
@@ -503,54 +345,13 @@ _thread_kern_scheduler(void)
gettimeofday((struct timeval *) &_sched_tod, NULL);
/* Check once more for a runnable thread: */
- _queue_signals = 1;
pthread_h = PTHREAD_PRIOQ_FIRST();
- _queue_signals = 0;
}
if (pthread_h != NULL) {
/* Remove the thread from the ready queue: */
PTHREAD_PRIOQ_REMOVE(pthread_h);
- /* Unprotect the scheduling queues: */
- _queue_signals = 0;
-
- /*
- * Check for signals queued while the scheduling
- * queues were protected:
- */
- while (_sigq_check_reqd != 0) {
- /* Clear before handling queued signals: */
- _sigq_check_reqd = 0;
-
- /* Protect the scheduling queues again: */
- _queue_signals = 1;
-
- dequeue_signals();
-
- /*
- * Check for a higher priority thread that
- * became runnable due to signal handling.
- */
- if (((pthread = PTHREAD_PRIOQ_FIRST()) != NULL) &&
- (pthread->active_priority > pthread_h->active_priority)) {
- /* Remove the thread from the ready queue: */
- PTHREAD_PRIOQ_REMOVE(pthread);
-
- /*
- * Insert the lower priority thread
- * at the head of its priority list:
- */
- PTHREAD_PRIOQ_INSERT_HEAD(pthread_h);
-
- /* There's a new thread in town: */
- pthread_h = pthread;
- }
-
- /* Unprotect the scheduling queues: */
- _queue_signals = 0;
- }
-
/* Make the selected thread the current thread: */
_set_curthread(pthread_h);
curthread = pthread_h;
@@ -584,13 +385,7 @@ _thread_kern_scheduler(void)
/*
* Continue the thread at its current frame:
*/
-#if NOT_YET
- _setcontext(&curthread->ctx.uc);
-#else
- ___longjmp(curthread->ctx.jb, 1);
-#endif
- /* This point should not be reached. */
- PANIC("Thread has returned from sigreturn or longjmp");
+ swapcontext(&_thread_kern_sched_ctx, &curthread->ctx);
}
}
@@ -610,19 +405,13 @@ _thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
*/
_thread_kern_in_sched = 1;
- /*
- * Prevent the signal handler from fiddling with this thread
- * before its state is set and is placed into the proper queue.
- */
- _queue_signals = 1;
-
/* Change the state of the current thread: */
curthread->state = state;
curthread->fname = fname;
curthread->lineno = lineno;
/* Schedule the next thread that is ready: */
- _thread_kern_sched(NULL);
+ _thread_kern_sched();
}
void
@@ -638,13 +427,6 @@ _thread_kern_sched_state_unlock(enum pthread_state state,
*/
_thread_kern_in_sched = 1;
- /*
- * Prevent the signal handler from fiddling with this thread
- * before its state is set and it is placed into the proper
- * queue(s).
- */
- _queue_signals = 1;
-
/* Change the state of the current thread: */
curthread->state = state;
curthread->fname = fname;
@@ -653,13 +435,12 @@ _thread_kern_sched_state_unlock(enum pthread_state state,
_SPINUNLOCK(lock);
/* Schedule the next thread that is ready: */
- _thread_kern_sched(NULL);
+ _thread_kern_sched();
}
static void
-thread_kern_poll(int wait_reqd)
+thread_kern_idle()
{
- int count = 0;
int i, found;
int kern_pipe_added = 0;
int nfds = 0;
@@ -668,57 +449,35 @@ thread_kern_poll(int wait_reqd)
struct timespec ts;
struct timeval tv;
- /* Check if the caller wants to wait: */
- if (wait_reqd == 0) {
- timeout_ms = 0;
- }
- else {
- /* Get the current time of day: */
- GET_CURRENT_TOD(tv);
- TIMEVAL_TO_TIMESPEC(&tv, &ts);
+ /* Get the current time of day: */
+ GET_CURRENT_TOD(tv);
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
- _queue_signals = 1;
- pthread = TAILQ_FIRST(&_waitingq);
- _queue_signals = 0;
+ pthread = TAILQ_FIRST(&_waitingq);
- if ((pthread == NULL) || (pthread->wakeup_time.tv_sec == -1)) {
- /*
- * Either there are no threads in the waiting queue,
- * or there are no threads that can timeout.
- */
- timeout_ms = INFTIM;
- }
- else if (pthread->wakeup_time.tv_sec - ts.tv_sec > 60000)
- /* Limit maximum timeout to prevent rollover. */
- timeout_ms = 60000;
- else {
- /*
- * Calculate the time left for the next thread to
- * timeout:
- */
- timeout_ms = ((pthread->wakeup_time.tv_sec - ts.tv_sec) *
- 1000) + ((pthread->wakeup_time.tv_nsec - ts.tv_nsec) /
- 1000000);
- /*
- * Don't allow negative timeouts:
- */
- if (timeout_ms < 0)
- timeout_ms = 0;
- }
+ if ((pthread == NULL) || (pthread->wakeup_time.tv_sec == -1)) {
+ /*
+ * Either there are no threads in the waiting queue,
+ * or there are no threads that can timeout.
+ */
+ PANIC("Would idle forever");
}
-
- /* Protect the scheduling queues: */
- _queue_signals = 1;
-
- /*
- * Check to see if the signal queue needs to be walked to look
- * for threads awoken by a signal while in the scheduler.
- */
- if (_sigq_check_reqd != 0) {
- /* Reset flag before handling queued signals: */
- _sigq_check_reqd = 0;
-
- dequeue_signals();
+ else if (pthread->wakeup_time.tv_sec - ts.tv_sec > 60000)
+ /* Limit maximum timeout to prevent rollover. */
+ timeout_ms = 60000;
+ else {
+ /*
+ * Calculate the time left for the next thread to
+ * timeout:
+ */
+ timeout_ms = ((pthread->wakeup_time.tv_sec - ts.tv_sec) *
+ 1000) + ((pthread->wakeup_time.tv_nsec - ts.tv_nsec) /
+ 1000000);
+ /*
+ * Only idle if we would be.
+ */
+ if (timeout_ms <= 0)
+ return;
}
/*
@@ -733,219 +492,11 @@ thread_kern_poll(int wait_reqd)
}
/*
- * Form the poll table:
+ * Idle.
*/
- nfds = 0;
- if (timeout_ms != 0) {
- /* Add the kernel pipe to the poll table: */
- _thread_pfd_table[nfds].fd = _thread_kern_pipe[0];
- _thread_pfd_table[nfds].events = POLLRDNORM;
- _thread_pfd_table[nfds].revents = 0;
- nfds++;
- kern_pipe_added = 1;
- }
-
- PTHREAD_WAITQ_SETACTIVE();
- TAILQ_FOREACH(pthread, &_workq, qe) {
- switch (pthread->state) {
- case PS_SPINBLOCK:
- /*
- * If the lock is available, let the thread run.
- */
- if (pthread->data.spinlock->access_lock == 0) {
- PTHREAD_WAITQ_CLEARACTIVE();
- PTHREAD_WORKQ_REMOVE(pthread);
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- PTHREAD_WAITQ_SETACTIVE();
- /* One less thread in a spinblock state: */
- _spinblock_count--;
- /*
- * Since there is at least one runnable
- * thread, disable the wait.
- */
- timeout_ms = 0;
- }
- break;
-
- /* File descriptor read wait: */
- case PS_FDR_WAIT:
- /* Limit number of polled files to table size: */
- if (nfds < _thread_dtablesize) {
- _thread_pfd_table[nfds].events = POLLRDNORM;
- _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
- nfds++;
- }
- break;
-
- /* File descriptor write wait: */
- case PS_FDW_WAIT:
- /* Limit number of polled files to table size: */
- if (nfds < _thread_dtablesize) {
- _thread_pfd_table[nfds].events = POLLWRNORM;
- _thread_pfd_table[nfds].fd = pthread->data.fd.fd;
- nfds++;
- }
- break;
-
- /* File descriptor poll or select wait: */
- case PS_POLL_WAIT:
- case PS_SELECT_WAIT:
- /* Limit number of polled files to table size: */
- if (pthread->data.poll_data->nfds + nfds <
- _thread_dtablesize) {
- for (i = 0; i < pthread->data.poll_data->nfds; i++) {
- _thread_pfd_table[nfds + i].fd =
- pthread->data.poll_data->fds[i].fd;
- _thread_pfd_table[nfds + i].events =
- pthread->data.poll_data->fds[i].events;
- }
- nfds += pthread->data.poll_data->nfds;
- }
- break;
-
- /* Other states do not depend on file I/O. */
- default:
- break;
- }
- }
- PTHREAD_WAITQ_CLEARACTIVE();
-
- /*
- * Wait for a file descriptor to be ready for read, write, or
- * an exception, or a timeout to occur:
- */
- count = __sys_poll(_thread_pfd_table, nfds, timeout_ms);
-
- if (kern_pipe_added != 0)
- /*
- * Remove the pthread kernel pipe file descriptor
- * from the pollfd table:
- */
- nfds = 1;
- else
- nfds = 0;
-
- /*
- * Check if it is possible that there are bytes in the kernel
- * read pipe waiting to be read:
- */
- if (count < 0 || ((kern_pipe_added != 0) &&
- (_thread_pfd_table[0].revents & POLLRDNORM))) {
- /*
- * If the kernel read pipe was included in the
- * count:
- */
- if (count > 0) {
- /* Decrement the count of file descriptors: */
- count--;
- }
-
- if (_sigq_check_reqd != 0) {
- /* Reset flag before handling signals: */
- _sigq_check_reqd = 0;
-
- dequeue_signals();
- }
- }
-
- /*
- * Check if any file descriptors are ready:
- */
- if (count > 0) {
- /*
- * Enter a loop to look for threads waiting on file
- * descriptors that are flagged as available by the
- * _poll syscall:
- */
- PTHREAD_WAITQ_SETACTIVE();
- TAILQ_FOREACH(pthread, &_workq, qe) {
- switch (pthread->state) {
- case PS_SPINBLOCK:
- /*
- * If the lock is available, let the thread run.
- */
- if (pthread->data.spinlock->access_lock == 0) {
- PTHREAD_WAITQ_CLEARACTIVE();
- PTHREAD_WORKQ_REMOVE(pthread);
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- PTHREAD_WAITQ_SETACTIVE();
-
- /*
- * One less thread in a spinblock state:
- */
- _spinblock_count--;
- }
- break;
-
- /* File descriptor read wait: */
- case PS_FDR_WAIT:
- if ((nfds < _thread_dtablesize) &&
- (_thread_pfd_table[nfds].revents
- & (POLLRDNORM|POLLERR|POLLHUP|POLLNVAL))
- != 0) {
- PTHREAD_WAITQ_CLEARACTIVE();
- PTHREAD_WORKQ_REMOVE(pthread);
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- PTHREAD_WAITQ_SETACTIVE();
- }
- nfds++;
- break;
-
- /* File descriptor write wait: */
- case PS_FDW_WAIT:
- if ((nfds < _thread_dtablesize) &&
- (_thread_pfd_table[nfds].revents
- & (POLLWRNORM|POLLERR|POLLHUP|POLLNVAL))
- != 0) {
- PTHREAD_WAITQ_CLEARACTIVE();
- PTHREAD_WORKQ_REMOVE(pthread);
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- PTHREAD_WAITQ_SETACTIVE();
- }
- nfds++;
- break;
-
- /* File descriptor poll or select wait: */
- case PS_POLL_WAIT:
- case PS_SELECT_WAIT:
- if (pthread->data.poll_data->nfds + nfds <
- _thread_dtablesize) {
- /*
- * Enter a loop looking for I/O
- * readiness:
- */
- found = 0;
- for (i = 0; i < pthread->data.poll_data->nfds; i++) {
- if (_thread_pfd_table[nfds + i].revents != 0) {
- pthread->data.poll_data->fds[i].revents =
- _thread_pfd_table[nfds + i].revents;
- found++;
- }
- }
-
- /* Increment before destroying: */
- nfds += pthread->data.poll_data->nfds;
-
- if (found != 0) {
- pthread->data.poll_data->nfds = found;
- PTHREAD_WAITQ_CLEARACTIVE();
- PTHREAD_WORKQ_REMOVE(pthread);
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- PTHREAD_WAITQ_SETACTIVE();
- }
- }
- else
- nfds += pthread->data.poll_data->nfds;
- break;
+ __sys_poll(NULL, 0, timeout_ms);
- /* Other states do not depend on file I/O. */
- default:
- break;
- }
- }
- PTHREAD_WAITQ_CLEARACTIVE();
- }
- else if (_spinblock_count != 0) {
+ if (_spinblock_count != 0) {
/*
* Enter a loop to look for threads waiting on a spinlock
* that is now available.
@@ -971,22 +522,6 @@ thread_kern_poll(int wait_reqd)
}
PTHREAD_WAITQ_CLEARACTIVE();
}
-
- /* Unprotect the scheduling queues: */
- _queue_signals = 0;
-
- while (_sigq_check_reqd != 0) {
- /* Handle queued signals: */
- _sigq_check_reqd = 0;
-
- /* Protect the scheduling queues: */
- _queue_signals = 1;
-
- dequeue_signals();
-
- /* Unprotect the scheduling queues: */
- _queue_signals = 0;
- }
}
void
@@ -1058,54 +593,13 @@ _thread_kern_sig_undefer(void)
curthread->sig_defer_count = 0;
/*
- * Check if there are queued signals:
- */
- if (_sigq_check_reqd != 0)
- _thread_kern_sched(NULL);
-
- /*
* Check for asynchronous cancellation before delivering any
* pending signals:
*/
if (((curthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) &&
((curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0))
pthread_testcancel();
-
- /*
- * If there are pending signals or this thread has
- * to yield the CPU, call the kernel scheduler:
- *
- * XXX - Come back and revisit the pending signal problem
- */
- if ((curthread->yield_on_sig_undefer != 0) ||
- SIGNOTEMPTY(curthread->sigpend)) {
- curthread->yield_on_sig_undefer = 0;
- _thread_kern_sched(NULL);
- }
- }
-}
-
-static void
-dequeue_signals(void)
-{
- char bufr[128];
- int num;
-
- /*
- * Enter a loop to clear the pthread kernel pipe:
- */
- while (((num = __sys_read(_thread_kern_pipe[0], bufr,
- sizeof(bufr))) > 0) || (num == -1 && errno == EINTR)) {
- }
- if ((num < 0) && (errno != EAGAIN)) {
- /*
- * The only error we should expect is if there is
- * no data to read.
- */
- PANIC("Unable to read from thread kernel pipe");
}
- /* Handle any pending signals: */
- _thread_sig_handle_pending();
}
static inline void
diff --git a/lib/libpthread/thread/thr_kill.c b/lib/libpthread/thread/thr_kill.c
index a8a1fc6..24f9150 100644
--- a/lib/libpthread/thread/thr_kill.c
+++ b/lib/libpthread/thread/thr_kill.c
@@ -41,34 +41,8 @@ __weak_reference(_pthread_kill, pthread_kill);
int
_pthread_kill(pthread_t pthread, int sig)
{
- int ret;
-
- /* Check for invalid signal numbers: */
- if (sig < 0 || sig >= NSIG)
- /* Invalid signal: */
- ret = EINVAL;
/*
- * Ensure the thread is in the list of active threads, and the
- * signal is valid (signal 0 specifies error checking only) and
- * not being ignored:
+ * All signals are unsupported.
*/
- else if (((ret = _find_thread(pthread)) == 0) && (sig > 0) &&
- (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
- /*
- * Defer signals to protect the scheduling queues from
- * access by the signal handler:
- */
- _thread_kern_sig_defer();
-
- _thread_sig_send(pthread, sig);
-
- /*
- * Undefer and handle pending signals, yielding if
- * necessary:
- */
- _thread_kern_sig_undefer();
- }
-
- /* Return the completion status: */
- return (ret);
+ return (EINVAL);
}
diff --git a/lib/libpthread/thread/thr_msync.c b/lib/libpthread/thread/thr_msync.c
index 4d9a950..302f314f 100644
--- a/lib/libpthread/thread/thr_msync.c
+++ b/lib/libpthread/thread/thr_msync.c
@@ -14,16 +14,6 @@
__weak_reference(__msync, msync);
int
-_msync(void *addr, size_t len, int flags)
-{
- int ret;
-
- ret = __sys_msync(addr, len, flags);
-
- return (ret);
-}
-
-int
__msync(void *addr, size_t len, int flags)
{
int ret;
@@ -35,7 +25,7 @@ __msync(void *addr, size_t len, int flags)
* a cancellation point, as per the standard. sigh.
*/
_thread_enter_cancellation_point();
- ret = _msync(addr, len, flags);
+ ret = __sys_msync(addr, len, flags);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_open.c b/lib/libpthread/thread/thr_open.c
index 3e0da32..b8a6635 100644
--- a/lib/libpthread/thread/thr_open.c
+++ b/lib/libpthread/thread/thr_open.c
@@ -43,36 +43,6 @@
__weak_reference(__open, open);
int
-_open(const char *path, int flags,...)
-{
- int fd;
- int mode = 0;
- va_list ap;
-
- /* Check if the file is being created: */
- if (flags & O_CREAT) {
- /* Get the creation mode: */
- va_start(ap, flags);
- mode = va_arg(ap, int);
- va_end(ap);
- }
- /* Open the file: */
- if ((fd = __sys_open(path, flags, mode)) < 0) {
- }
- /* Initialise the file descriptor table entry: */
- else if (_thread_fd_table_init(fd) != 0) {
- /* Quietly close the file: */
- __sys_close(fd);
-
- /* Reset the file descriptor: */
- fd = -1;
- }
-
- /* Return the file descriptor or -1 on error: */
- return (fd);
-}
-
-int
__open(const char *path, int flags,...)
{
int ret;
@@ -89,7 +59,7 @@ __open(const char *path, int flags,...)
va_end(ap);
}
- ret = _open(path, flags, mode);
+ ret = __sys_open(path, flags, mode);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_poll.c b/lib/libpthread/thread/thr_poll.c
index b4c495c..353b3cc 100644
--- a/lib/libpthread/thread/thr_poll.c
+++ b/lib/libpthread/thread/thr_poll.c
@@ -43,68 +43,13 @@
__weak_reference(__poll, poll);
-int
-_poll(struct pollfd *fds, unsigned int nfds, int timeout)
-{
- struct pthread *curthread = _get_curthread();
- struct timespec ts;
- int numfds = nfds;
- int i, ret = 0;
- struct pthread_poll_data data;
-
- if (numfds > _thread_dtablesize) {
- numfds = _thread_dtablesize;
- }
- /* Check if a timeout was specified: */
- if (timeout == INFTIM) {
- /* Wait for ever: */
- _thread_kern_set_timeout(NULL);
- } else if (timeout > 0) {
- /* Convert the timeout in msec to a timespec: */
- ts.tv_sec = timeout / 1000;
- ts.tv_nsec = (timeout % 1000) * 1000000;
-
- /* Set the wake up time: */
- _thread_kern_set_timeout(&ts);
- } else if (timeout < 0) {
- /* a timeout less than zero but not == INFTIM is invalid */
- errno = EINVAL;
- return (-1);
- }
-
- if (((ret = __sys_poll(fds, numfds, 0)) == 0) && (timeout != 0)) {
- data.nfds = numfds;
- data.fds = fds;
-
- /*
- * Clear revents in case of a timeout which leaves fds
- * unchanged:
- */
- for (i = 0; i < numfds; i++) {
- fds[i].revents = 0;
- }
-
- curthread->data.poll_data = &data;
- curthread->interrupted = 0;
- _thread_kern_sched_state(PS_POLL_WAIT, __FILE__, __LINE__);
- if (curthread->interrupted) {
- errno = EINTR;
- ret = -1;
- } else {
- ret = data.nfds;
- }
- }
-
- return (ret);
-}
-
int
__poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
int ret;
_thread_enter_cancellation_point();
- ret = _poll(fds, nfds, timeout);
+ ret = __sys_poll(fds, nfds, timeout);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_priority_queue.c b/lib/libpthread/thread/thr_priority_queue.c
index b938a3c..1c1b269e 100644
--- a/lib/libpthread/thread/thr_priority_queue.c
+++ b/lib/libpthread/thread/thr_priority_queue.c
@@ -70,8 +70,8 @@ static int _pq_active = 0;
} while (0)
#define _PQ_ASSERT_PROTECTED(msg) \
PTHREAD_ASSERT((_thread_kern_in_sched != 0) || \
- ((_get_curthread())->sig_defer_count > 0) ||\
- (_sig_in_handler != 0), msg);
+ ((_get_curthread())->sig_defer_count > 0), \
+ msg);
#else
diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h
index 4db52d9..2f49804 100644
--- a/lib/libpthread/thread/thr_private.h
+++ b/lib/libpthread/thread/thr_private.h
@@ -49,7 +49,6 @@
/*
* Include files.
*/
-#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <sys/queue.h>
@@ -62,50 +61,6 @@
#include <pthread_np.h>
/*
- * Define machine dependent macros to get and set the stack pointer
- * from the supported contexts. Also define a macro to set the return
- * address in a jmp_buf context.
- *
- * XXX - These need to be moved into architecture dependent support files.
- */
-#if defined(__i386__)
-#define GET_STACK_JB(jb) ((unsigned long)((jb)[0]._jb[2]))
-#define GET_STACK_SJB(sjb) ((unsigned long)((sjb)[0]._sjb[2]))
-#define GET_STACK_UC(ucp) ((unsigned long)((ucp)->uc_mcontext.mc_esp))
-#define SET_STACK_JB(jb, stk) (jb)[0]._jb[2] = (int)(stk)
-#define SET_STACK_SJB(sjb, stk) (sjb)[0]._sjb[2] = (int)(stk)
-#define SET_STACK_UC(ucp, stk) (ucp)->uc_mcontext.mc_esp = (int)(stk)
-#define FP_SAVE_UC(ucp) do { \
- char *fdata; \
- fdata = (char *) (ucp)->uc_mcontext.mc_fpregs; \
- __asm__("fnsave %0": :"m"(*fdata)); \
-} while (0)
-#define FP_RESTORE_UC(ucp) do { \
- char *fdata; \
- fdata = (char *) (ucp)->uc_mcontext.mc_fpregs; \
- __asm__("frstor %0": :"m"(*fdata)); \
-} while (0)
-#define SET_RETURN_ADDR_JB(jb, ra) (jb)[0]._jb[0] = (int)(ra)
-#elif defined(__alpha__)
-#include <machine/reg.h>
-#define GET_STACK_JB(jb) ((unsigned long)((jb)[0]._jb[R_SP + 4]))
-#define GET_STACK_SJB(sjb) ((unsigned long)((sjb)[0]._sjb[R_SP + 4]))
-#define GET_STACK_UC(ucp) ((ucp)->uc_mcontext.mc_regs[R_SP])
-#define SET_STACK_JB(jb, stk) (jb)[0]._jb[R_SP + 4] = (long)(stk)
-#define SET_STACK_SJB(sjb, stk) (sjb)[0]._sjb[R_SP + 4] = (long)(stk)
-#define SET_STACK_UC(ucp, stk) (ucp)->uc_mcontext.mc_regs[R_SP] = (unsigned long)(stk)
-#define FP_SAVE_UC(ucp)
-#define FP_RESTORE_UC(ucp)
-#define SET_RETURN_ADDR_JB(jb, ra) do { \
- (jb)[0]._jb[2] = (long)(ra); \
- (jb)[0]._jb[R_RA + 4] = (long)(ra); \
- (jb)[0]._jb[R_T12 + 4] = (long)(ra); \
-} while (0)
-#else
-#error "Don't recognize this architecture!"
-#endif
-
-/*
* Kernel fatal error handler macro.
*/
#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
@@ -217,17 +172,6 @@
#endif
/*
- * Define the signals to be used for scheduling.
- */
-#if defined(_PTHREADS_COMPAT_SCHED)
-#define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL
-#define _SCHED_SIGNAL SIGVTALRM
-#else
-#define _ITIMER_SCHED_TIMER ITIMER_PROF
-#define _SCHED_SIGNAL SIGPROF
-#endif
-
-/*
* Priority queues.
*
* XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
@@ -487,20 +431,10 @@ struct pthread_rwlock {
*/
enum pthread_state {
PS_RUNNING,
- PS_SIGTHREAD,
PS_MUTEX_WAIT,
PS_COND_WAIT,
- PS_FDLR_WAIT,
- PS_FDLW_WAIT,
- PS_FDR_WAIT,
- PS_FDW_WAIT,
- PS_FILE_WAIT,
- PS_POLL_WAIT,
- PS_SELECT_WAIT,
PS_SLEEP_WAIT,
PS_WAIT_WAIT,
- PS_SIGSUSPEND,
- PS_SIGWAIT,
PS_SPINBLOCK,
PS_JOIN,
PS_SUSPENDED,
@@ -517,46 +451,9 @@ enum pthread_state {
#define FD_WRITE 0x2
#define FD_RDWR (FD_READ | FD_WRITE)
-/*
- * File descriptor table structure.
- */
-struct fd_table_entry {
- /*
- * Lock for accesses to this file descriptor table
- * entry. This is passed to _spinlock() to provide atomic
- * access to this structure. It does *not* represent the
- * state of the lock on the file descriptor.
- */
- spinlock_t lock;
- TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
- TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
- struct pthread *r_owner; /* Ptr to thread owning read lock. */
- struct pthread *w_owner; /* Ptr to thread owning write lock. */
- char *r_fname; /* Ptr to read lock source file name */
- int r_lineno; /* Read lock source line number. */
- char *w_fname; /* Ptr to write lock source file name */
- int w_lineno; /* Write lock source line number. */
- int r_lockcount; /* Count for FILE read locks. */
- int w_lockcount; /* Count for FILE write locks. */
- int flags; /* Flags used in open. */
-};
-
-struct pthread_poll_data {
- int nfds;
- struct pollfd *fds;
-};
-
union pthread_wait_data {
pthread_mutex_t mutex;
pthread_cond_t cond;
- const sigset_t *sigwait; /* Waiting on a signal in sigwait */
- struct {
- short fd; /* Used when thread waiting on fd */
- short branch; /* Line number, for debugging. */
- char *fname; /* Source file name for debugging.*/
- } fd;
- FILE *fp;
- struct pthread_poll_data *poll_data;
spinlock_t *spinlock;
struct pthread *thread;
};
@@ -567,52 +464,12 @@ union pthread_wait_data {
*/
typedef void (*thread_continuation_t) (void *);
-struct pthread_signal_frame;
-
-struct pthread_state_data {
- struct pthread_signal_frame *psd_curframe;
- sigset_t psd_sigmask;
- struct timespec psd_wakeup_time;
- union pthread_wait_data psd_wait_data;
- enum pthread_state psd_state;
- int psd_flags;
- int psd_interrupted;
- int psd_longjmp_val;
- int psd_sigmask_seqno;
- int psd_signo;
- int psd_sig_defer_count;
- /* XXX - What about thread->timeout and/or thread->error? */
-};
-
struct join_status {
struct pthread *thread;
void *ret;
int error;
};
-/*
- * The frame that is added to the top of a threads stack when setting up
- * up the thread to run a signal handler.
- */
-struct pthread_signal_frame {
- /*
- * This stores the threads state before the signal.
- */
- struct pthread_state_data saved_state;
-
- /*
- * Threads return context; we use only jmp_buf's for now.
- */
- union {
- jmp_buf jb;
- ucontext_t uc;
- } ctx;
- int signo; /* signal, arg 1 to sighandler */
- int sig_has_args; /* use signal args if true */
- ucontext_t uc;
- siginfo_t siginfo;
-};
-
struct pthread_specific_elem {
const void *data;
int seqno;
@@ -652,19 +509,11 @@ struct pthread {
struct pthread_attr attr;
/*
- * Threads return context; we use only jmp_buf's for now.
+ * Machine context, including signal state.
*/
- union {
- jmp_buf jb;
- ucontext_t uc;
- } ctx;
+ ucontext_t ctx;
/*
- * Used for tracking delivery of signal handlers.
- */
- struct pthread_signal_frame *curframe;
-
- /*
* Cancelability flags - the lower 2 bits are used by cancel
* definitions in pthread.h
*/
@@ -675,14 +524,6 @@ struct pthread {
thread_continuation_t continuation;
- /*
- * Current signal mask and pending signals.
- */
- sigset_t sigmask;
- sigset_t sigpend;
- int sigmask_seqno;
- int check_pending;
-
/* Thread state: */
enum pthread_state state;
@@ -700,7 +541,7 @@ struct pthread {
/*
* Time to wake up thread. This is used for sleeping threads and
- * for any operation which may time out (such as select).
+ * for any operation which may time out.
*/
struct timespec wakeup_time;
@@ -753,31 +594,17 @@ struct pthread {
union pthread_wait_data data;
/*
- * Allocated for converting select into poll.
- */
- struct pthread_poll_data poll_data;
-
- /*
* Set to TRUE if a blocking operation was
* interrupted by a signal:
*/
int interrupted;
- /* Signal number when in state PS_SIGWAIT: */
- int signo;
-
/*
* Set to non-zero when this thread has deferred signals.
* We allow for recursive deferral.
*/
int sig_defer_count;
- /*
- * Set to TRUE if this thread should yield after undeferring
- * signals.
- */
- int yield_on_sig_undefer;
-
/* Miscellaneous flags; only set with signals deferred. */
int flags;
#define PTHREAD_FLAGS_PRIVATE 0x0001
@@ -786,7 +613,7 @@ struct pthread {
#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */
#define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */
#define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */
-#define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */
+ /* 0x0040 Unused. */
#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/
#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */
#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */
@@ -876,25 +703,6 @@ SCLASS TAILQ_HEAD(, pthread) _thread_list
;
#endif
-/*
- * Array of kernel pipe file descriptors that are used to ensure that
- * no signals are missed in calls to _select.
- */
-SCLASS int _thread_kern_pipe[2]
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= {
- -1,
- -1
-};
-#else
-;
-#endif
-SCLASS int volatile _queue_signals
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= 0;
-#else
-;
-#endif
SCLASS int _thread_kern_in_sched
#ifdef GLOBAL_PTHREAD_PRIVATE
= 0;
@@ -902,13 +710,6 @@ SCLASS int _thread_kern_in_sched
;
#endif
-SCLASS int _sig_in_handler
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= 0;
-#else
-;
-#endif
-
/* Time of day at last scheduling timer signal: */
SCLASS struct timeval volatile _sched_tod
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -969,42 +770,6 @@ SCLASS struct pthread_cond_attr pthread_condattr_default
;
#endif
-/*
- * Standard I/O file descriptors need special flag treatment since
- * setting one to non-blocking does all on *BSD. Sigh. This array
- * is used to store the initial flag settings.
- */
-SCLASS int _pthread_stdio_flags[3];
-
-/* File table information: */
-SCLASS struct fd_table_entry **_thread_fd_table
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= NULL;
-#else
-;
-#endif
-
-/* Table for polling file descriptors: */
-SCLASS struct pollfd *_thread_pfd_table
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= NULL;
-#else
-;
-#endif
-
-SCLASS const int dtablecount
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= 4096/sizeof(struct fd_table_entry);
-#else
-;
-#endif
-SCLASS int _thread_dtablesize /* Descriptor table size. */
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= 0;
-#else
-;
-#endif
-
SCLASS int _clock_res_usec /* Clock resolution in usec. */
#ifdef GLOBAL_PTHREAD_PRIVATE
= CLOCK_RES_USEC;
@@ -1025,28 +790,6 @@ SCLASS pthread_cond_t _gc_cond
;
/*
- * Array of signal actions for this process.
- */
-SCLASS struct sigaction _thread_sigact[NSIG];
-
-/*
- * Array of counts of dummy handlers for SIG_DFL signals. This is used to
- * assure that there is always a dummy signal handler installed while there is a
- * thread sigwait()ing on the corresponding signal.
- */
-SCLASS int _thread_dfl_count[NSIG];
-
-/*
- * Pending signals and mask for this process:
- */
-SCLASS sigset_t _process_sigpending;
-SCLASS sigset_t _process_sigmask
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= { {0, 0, 0, 0} }
-#endif
-;
-
-/*
* Scheduling queues:
*/
SCLASS pq_queue_t _readyq;
@@ -1064,28 +807,6 @@ SCLASS volatile int _spinblock_count
#endif
;
-/* Used to maintain pending and active signals: */
-struct sigstatus {
- int pending; /* Is this a pending signal? */
- int blocked; /*
- * A handler is currently active for
- * this signal; ignore subsequent
- * signals until the handler is done.
- */
- int signo; /* arg 1 to signal handler */
- siginfo_t siginfo; /* arg 2 to signal handler */
- ucontext_t uc; /* arg 3 to signal handler */
-};
-
-SCLASS struct sigstatus _thread_sigq[NSIG];
-
-/* Indicates that the signal queue needs to be checked. */
-SCLASS volatile int _sigq_check_reqd
-#ifdef GLOBAL_PTHREAD_PRIVATE
-= 0
-#endif
-;
-
/* Thread switch hook. */
SCLASS pthread_switch_routine_t _sched_switch_hook
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -1096,9 +817,9 @@ SCLASS pthread_switch_routine_t _sched_switch_hook
/*
* Declare the kernel scheduler jump buffer and stack:
*/
-SCLASS jmp_buf _thread_kern_sched_jb;
+SCLASS ucontext_t _thread_kern_sched_ctx;
-SCLASS void * _thread_kern_sched_stack
+SCLASS void * _thread_kern_sched_stack
#ifdef GLOBAL_PTHREAD_PRIVATE
= NULL
#endif
@@ -1115,16 +836,6 @@ SCLASS int _thread_kern_new_state
/* Undefine the storage class specifier: */
#undef SCLASS
-#ifdef _LOCK_DEBUG
-#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
- _ts, __FILE__, __LINE__)
-#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \
- __FILE__, __LINE__)
-#else
-#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
-#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
-#endif
-
/*
* Function prototype definitions.
*/
@@ -1133,7 +844,6 @@ char *__ttyname_basic(int);
char *__ttyname_r_basic(int, char *, size_t);
char *ttyname_r(int, char *, size_t);
void _cond_wait_backout(pthread_t);
-void _fd_lock_backout(pthread_t);
int _find_thread(pthread_t);
struct pthread *_get_curthread(void);
void _set_curthread(struct pthread *);
@@ -1175,35 +885,18 @@ void _waitq_clearactive(void);
#endif
void _thread_exit(char *, int, char *);
void _thread_exit_cleanup(void);
-int _thread_fd_getflags(int);
-int _thread_fd_lock(int, int, struct timespec *);
-int _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno);
-void _thread_fd_setflags(int, int);
-int _thread_fd_table_init(int fd);
-void _thread_fd_unlock(int, int);
-void _thread_fd_unlock_debug(int, int, char *, int);
-void _thread_fd_unlock_owned(pthread_t);
void *_thread_cleanup(pthread_t);
void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void);
-void _thread_kern_sched(ucontext_t *);
+void _thread_kern_sched(void);
void _thread_kern_scheduler(void);
-void _thread_kern_sched_frame(struct pthread_signal_frame *psf);
-void _thread_kern_sched_sig(void);
void _thread_kern_sched_state(enum pthread_state, char *fname, int lineno);
void _thread_kern_sched_state_unlock(enum pthread_state state,
spinlock_t *lock, char *fname, int lineno);
void _thread_kern_set_timeout(const struct timespec *);
void _thread_kern_sig_defer(void);
void _thread_kern_sig_undefer(void);
-void _thread_sig_handler(int, siginfo_t *, ucontext_t *);
-void _thread_sig_check_pending(struct pthread *pthread);
-void _thread_sig_handle_pending(void);
-void _thread_sig_send(struct pthread *pthread, int sig);
-void _thread_sig_wrapper(void);
-void _thread_sigframe_restore(struct pthread *thread,
- struct pthread_signal_frame *psf);
void _thread_start(void);
void _thread_seterrno(pthread_t, int);
pthread_addr_t _thread_gc(pthread_addr_t);
@@ -1211,13 +904,6 @@ void _thread_enter_cancellation_point(void);
void _thread_leave_cancellation_point(void);
void _thread_cancellation_point(void);
-/* #include <sys/acl.h> */
-#ifdef _SYS_ACL_H
-int __sys___acl_aclcheck_fd(int, acl_type_t, struct acl *);
-int __sys___acl_delete_fd(int, acl_type_t);
-int __sys___acl_get_fd(int, acl_type_t, struct acl *);
-int __sys___acl_set_fd(int, acl_type_t, struct acl *);
-#endif
/* #include <sys/aio.h> */
#ifdef _SYS_AIO_H_
@@ -1324,12 +1010,6 @@ ssize_t __sys_read(int, void *, size_t);
ssize_t __sys_write(int, const void *, size_t);
#endif
-/* #include <setjmp.h> */
-#ifdef _SETJMP_H_
-extern void __siglongjmp(sigjmp_buf, int) __dead2;
-extern void __longjmp(jmp_buf, int) __dead2;
-extern void ___longjmp(jmp_buf, int) __dead2;
-#endif
__END_DECLS
#endif /* !_THR_PRIVATE_H */
diff --git a/lib/libpthread/thread/thr_read.c b/lib/libpthread/thread/thr_read.c
index f313a9c..8d095c4 100644
--- a/lib/libpthread/thread/thr_read.c
+++ b/lib/libpthread/thread/thr_read.c
@@ -43,68 +43,12 @@
__weak_reference(__read, read);
ssize_t
-_read(int fd, void *buf, size_t nbytes)
-{
- struct pthread *curthread = _get_curthread();
- int ret;
- int type;
-
- /* POSIX says to do just this: */
- if (nbytes == 0) {
- return (0);
- }
-
- /* Lock the file descriptor for read: */
- if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
- /* Get the read/write mode type: */
- type = _thread_fd_getflags(fd) & O_ACCMODE;
-
- /* Check if the file is not open for read: */
- if (type != O_RDONLY && type != O_RDWR) {
- /* File is not open for read: */
- errno = EBADF;
- _FD_UNLOCK(fd, FD_READ);
- return (-1);
- }
-
- /* Perform a non-blocking read syscall: */
- while ((ret = __sys_read(fd, buf, nbytes)) < 0) {
- if ((_thread_fd_getflags(fd) & O_NONBLOCK) == 0 &&
- (errno == EWOULDBLOCK || errno == EAGAIN)) {
- curthread->data.fd.fd = fd;
- _thread_kern_set_timeout(NULL);
-
- /* Reset the interrupted operation flag: */
- curthread->interrupted = 0;
-
- _thread_kern_sched_state(PS_FDR_WAIT,
- __FILE__, __LINE__);
-
- /*
- * Check if the operation was
- * interrupted by a signal
- */
- if (curthread->interrupted) {
- errno = EINTR;
- ret = -1;
- break;
- }
- } else {
- break;
- }
- }
- _FD_UNLOCK(fd, FD_READ);
- }
- return (ret);
-}
-
-ssize_t
__read(int fd, void *buf, size_t nbytes)
{
ssize_t ret;
_thread_enter_cancellation_point();
- ret = _read(fd, buf, nbytes);
+ ret = __sys_read(fd, buf, nbytes);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_readv.c b/lib/libpthread/thread/thr_readv.c
index 707c04c..c3b03eb 100644
--- a/lib/libpthread/thread/thr_readv.c
+++ b/lib/libpthread/thread/thr_readv.c
@@ -43,63 +43,12 @@
__weak_reference(__readv, readv);
ssize_t
-_readv(int fd, const struct iovec * iov, int iovcnt)
-{
- struct pthread *curthread = _get_curthread();
- int ret;
- int type;
-
- /* Lock the file descriptor for read: */
- if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
- /* Get the read/write mode type: */
- type = _thread_fd_getflags(fd) & O_ACCMODE;
-
- /* Check if the file is not open for read: */
- if (type != O_RDONLY && type != O_RDWR) {
- /* File is not open for read: */
- errno = EBADF;
- _FD_UNLOCK(fd, FD_READ);
- return (-1);
- }
-
- /* Perform a non-blocking readv syscall: */
- while ((ret = __sys_readv(fd, iov, iovcnt)) < 0) {
- if ((_thread_fd_getflags(fd) & O_NONBLOCK) == 0 &&
- (errno == EWOULDBLOCK || errno == EAGAIN)) {
- curthread->data.fd.fd = fd;
- _thread_kern_set_timeout(NULL);
-
- /* Reset the interrupted operation flag: */
- curthread->interrupted = 0;
-
- _thread_kern_sched_state(PS_FDR_WAIT,
- __FILE__, __LINE__);
-
- /*
- * Check if the operation was
- * interrupted by a signal
- */
- if (curthread->interrupted) {
- errno = EINTR;
- ret = -1;
- break;
- }
- } else {
- break;
- }
- }
- _FD_UNLOCK(fd, FD_READ);
- }
- return (ret);
-}
-
-ssize_t
__readv(int fd, const struct iovec *iov, int iovcnt)
{
ssize_t ret;
_thread_enter_cancellation_point();
- ret = _readv(fd, iov, iovcnt);
+ ret = __sys_readv(fd, iov, iovcnt);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_select.c b/lib/libpthread/thread/thr_select.c
index a041513..a4f4a15 100644
--- a/lib/libpthread/thread/thr_select.c
+++ b/lib/libpthread/thread/thr_select.c
@@ -46,185 +46,13 @@
__weak_reference(__select, select);
int
-_select(int numfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
- struct timeval * timeout)
-{
- struct pthread *curthread = _get_curthread();
- struct timespec ts;
- int i, ret = 0, f_wait = 1;
- int pfd_index, got_events = 0, fd_count = 0;
- struct pthread_poll_data data;
-
- if (numfds > _thread_dtablesize) {
- numfds = _thread_dtablesize;
- }
- /* Check if a timeout was specified: */
- if (timeout) {
- if (timeout->tv_sec < 0 ||
- timeout->tv_usec < 0 || timeout->tv_usec >= 1000000) {
- errno = EINVAL;
- return (-1);
- }
-
- /* Convert the timeval to a timespec: */
- TIMEVAL_TO_TIMESPEC(timeout, &ts);
-
- /* Set the wake up time: */
- _thread_kern_set_timeout(&ts);
- if (ts.tv_sec == 0 && ts.tv_nsec == 0)
- f_wait = 0;
- } else {
- /* Wait for ever: */
- _thread_kern_set_timeout(NULL);
- }
-
- /* Count the number of file descriptors to be polled: */
- if (readfds || writefds || exceptfds) {
- for (i = 0; i < numfds; i++) {
- if ((readfds && FD_ISSET(i, readfds)) ||
- (exceptfds && FD_ISSET(i, exceptfds)) ||
- (writefds && FD_ISSET(i, writefds))) {
- fd_count++;
- }
- }
- }
-
- /*
- * Allocate memory for poll data if it hasn't already been
- * allocated or if previously allocated memory is insufficient.
- */
- if ((curthread->poll_data.fds == NULL) ||
- (curthread->poll_data.nfds < fd_count)) {
- data.fds = (struct pollfd *) realloc(curthread->poll_data.fds,
- sizeof(struct pollfd) * MAX(128, fd_count));
- if (data.fds == NULL) {
- errno = ENOMEM;
- ret = -1;
- }
- else {
- /*
- * Note that the threads poll data always
- * indicates what is allocated, not what is
- * currently being polled.
- */
- curthread->poll_data.fds = data.fds;
- curthread->poll_data.nfds = MAX(128, fd_count);
- }
- }
- if (ret == 0) {
- /* Setup the wait data. */
- data.fds = curthread->poll_data.fds;
- data.nfds = fd_count;
-
- /*
- * Setup the array of pollfds. Optimize this by
- * running the loop in reverse and stopping when
- * the number of selected file descriptors is reached.
- */
- for (i = numfds - 1, pfd_index = fd_count - 1;
- (i >= 0) && (pfd_index >= 0); i--) {
- data.fds[pfd_index].events = 0;
- if (readfds && FD_ISSET(i, readfds)) {
- data.fds[pfd_index].events = POLLRDNORM;
- }
- if (exceptfds && FD_ISSET(i, exceptfds)) {
- data.fds[pfd_index].events |= POLLRDBAND;
- }
- if (writefds && FD_ISSET(i, writefds)) {
- data.fds[pfd_index].events |= POLLWRNORM;
- }
- if (data.fds[pfd_index].events != 0) {
- /*
- * Set the file descriptor to be polled and
- * clear revents in case of a timeout which
- * leaves fds unchanged:
- */
- data.fds[pfd_index].fd = i;
- data.fds[pfd_index].revents = 0;
- pfd_index--;
- }
- }
- if (((ret = __sys_poll(data.fds, data.nfds, 0)) == 0) &&
- (f_wait != 0)) {
- curthread->data.poll_data = &data;
- curthread->interrupted = 0;
- _thread_kern_sched_state(PS_SELECT_WAIT, __FILE__, __LINE__);
- if (curthread->interrupted) {
- errno = EINTR;
- data.nfds = 0;
- ret = -1;
- } else
- ret = data.nfds;
- }
- }
-
- if (ret >= 0) {
- numfds = 0;
- for (i = 0; i < fd_count; i++) {
- /*
- * Check the results of the poll and clear
- * this file descriptor from the fdset if
- * the requested event wasn't ready.
- */
-
- /*
- * First check for invalid descriptor.
- * If found, set errno and return -1.
- */
- if (data.fds[i].revents & POLLNVAL) {
- errno = EBADF;
- return -1;
- }
-
- got_events = 0;
- if (readfds != NULL) {
- if (FD_ISSET(data.fds[i].fd, readfds)) {
- if ((data.fds[i].revents & (POLLIN
- | POLLRDNORM | POLLERR
- | POLLHUP | POLLNVAL)) != 0)
- got_events++;
- else
- FD_CLR(data.fds[i].fd, readfds);
- }
- }
- if (writefds != NULL) {
- if (FD_ISSET(data.fds[i].fd, writefds)) {
- if ((data.fds[i].revents & (POLLOUT
- | POLLWRNORM | POLLWRBAND | POLLERR
- | POLLHUP | POLLNVAL)) != 0)
- got_events++;
- else
- FD_CLR(data.fds[i].fd,
- writefds);
- }
- }
- if (exceptfds != NULL) {
- if (FD_ISSET(data.fds[i].fd, exceptfds)) {
- if (data.fds[i].revents & (POLLRDBAND |
- POLLPRI))
- got_events++;
- else
- FD_CLR(data.fds[i].fd,
- exceptfds);
- }
- }
- if (got_events != 0)
- numfds+=got_events;
- }
- ret = numfds;
- }
-
- return (ret);
-}
-
-int
__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout)
{
int ret;
_thread_enter_cancellation_point();
- ret = _select(numfds, readfds, writefds, exceptfds, timeout);
+ ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_sigmask.c b/lib/libpthread/thread/thr_sigmask.c
index c26fefc..846062a 100644
--- a/lib/libpthread/thread/thr_sigmask.c
+++ b/lib/libpthread/thread/thr_sigmask.c
@@ -44,63 +44,6 @@ __weak_reference(_pthread_sigmask, pthread_sigmask);
int
_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
- struct pthread *curthread = _get_curthread();
- sigset_t sigset;
- int ret = 0;
- /* Check if the existing signal process mask is to be returned: */
- if (oset != NULL) {
- /* Return the current mask: */
- *oset = curthread->sigmask;
- }
- /* Check if a new signal set was provided by the caller: */
- if (set != NULL) {
- /* Process according to what to do: */
- switch (how) {
- /* Block signals: */
- case SIG_BLOCK:
- /* Add signals to the existing mask: */
- SIGSETOR(curthread->sigmask, *set);
- break;
-
- /* Unblock signals: */
- case SIG_UNBLOCK:
- /* Clear signals from the existing mask: */
- SIGSETNAND(curthread->sigmask, *set);
- break;
-
- /* Set the signal process mask: */
- case SIG_SETMASK:
- /* Set the new mask: */
- curthread->sigmask = *set;
- break;
-
- /* Trap invalid actions: */
- default:
- /* Return an invalid argument: */
- errno = EINVAL;
- ret = -1;
- break;
- }
-
- /* Increment the sequence number: */
- curthread->sigmask_seqno++;
-
- /*
- * Check if there are pending signals for the running
- * thread or process that aren't blocked:
- */
- sigset = curthread->sigpend;
- SIGSETOR(sigset, _process_sigpending);
- SIGSETNAND(sigset, curthread->sigmask);
- if (SIGNOTEMPTY(sigset))
- /*
- * Call the kernel scheduler which will safely
- * install a signal frame for the running thread:
- */
- _thread_kern_sched_sig();
- }
-
- /* Return the completion status: */
- return (ret);
+ return (sigprocmask(how, set, oset));
}
diff --git a/lib/libpthread/thread/thr_sigsuspend.c b/lib/libpthread/thread/thr_sigsuspend.c
index 90638f4..dc805ac 100644
--- a/lib/libpthread/thread/thr_sigsuspend.c
+++ b/lib/libpthread/thread/thr_sigsuspend.c
@@ -41,60 +41,12 @@
__weak_reference(__sigsuspend, sigsuspend);
int
-_sigsuspend(const sigset_t * set)
-{
- struct pthread *curthread = _get_curthread();
- int ret = -1;
- sigset_t oset, sigset;
-
- /* Check if a new signal set was provided by the caller: */
- if (set != NULL) {
- /* Save the current signal mask: */
- oset = curthread->sigmask;
-
- /* Change the caller's mask: */
- curthread->sigmask = *set;
-
- /*
- * Check if there are pending signals for the running
- * thread or process that aren't blocked:
- */
- sigset = curthread->sigpend;
- SIGSETOR(sigset, _process_sigpending);
- SIGSETNAND(sigset, curthread->sigmask);
- if (SIGNOTEMPTY(sigset)) {
- /*
- * Call the kernel scheduler which will safely
- * install a signal frame for the running thread:
- */
- _thread_kern_sched_sig();
- } else {
- /* Wait for a signal: */
- _thread_kern_sched_state(PS_SIGSUSPEND,
- __FILE__, __LINE__);
- }
-
- /* Always return an interrupted error: */
- errno = EINTR;
-
- /* Restore the signal mask: */
- curthread->sigmask = oset;
- } else {
- /* Return an invalid argument error: */
- errno = EINVAL;
- }
-
- /* Return the completion status: */
- return (ret);
-}
-
-int
__sigsuspend(const sigset_t * set)
{
int ret;
_thread_enter_cancellation_point();
- ret = _sigsuspend(set);
+ ret = __sys_sigsuspend(set);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_sigwait.c b/lib/libpthread/thread/thr_sigwait.c
index 209d3e7..3cc9ff0 100644
--- a/lib/libpthread/thread/thr_sigwait.c
+++ b/lib/libpthread/thread/thr_sigwait.c
@@ -1,3 +1,4 @@
+//depot/projects/kse/lib/libpthread/thread/thr_sigwait.c#1 - branch change 15154 (text+ko)
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -43,132 +44,9 @@ __weak_reference(_sigwait, sigwait);
int
_sigwait(const sigset_t *set, int *sig)
{
- struct pthread *curthread = _get_curthread();
- int ret = 0;
- int i;
- sigset_t tempset, waitset;
- struct sigaction act;
-
- _thread_enter_cancellation_point();
- /*
- * Specify the thread kernel signal handler.
- */
- act.sa_handler = (void (*) ()) _thread_sig_handler;
- act.sa_flags = SA_RESTART | SA_SIGINFO;
- /* Ensure the signal handler cannot be interrupted by other signals: */
- sigfillset(&act.sa_mask);
-
- /*
- * Initialize the set of signals that will be waited on:
- */
- waitset = *set;
-
- /* These signals can't be waited on. */
- sigdelset(&waitset, SIGKILL);
- sigdelset(&waitset, SIGSTOP);
- sigdelset(&waitset, _SCHED_SIGNAL);
- sigdelset(&waitset, SIGCHLD);
- sigdelset(&waitset, SIGINFO);
-
- /* Check to see if a pending signal is in the wait mask. */
- tempset = curthread->sigpend;
- SIGSETOR(tempset, _process_sigpending);
- SIGSETAND(tempset, waitset);
- if (SIGNOTEMPTY(tempset)) {
- /* Enter a loop to find a pending signal: */
- for (i = 1; i < NSIG; i++) {
- if (sigismember (&tempset, i))
- break;
- }
-
- /* Clear the pending signal: */
- if (sigismember(&curthread->sigpend,i))
- sigdelset(&curthread->sigpend,i);
- else
- sigdelset(&_process_sigpending,i);
-
- /* Return the signal number to the caller: */
- *sig = i;
-
- _thread_leave_cancellation_point();
- return (0);
- }
-
- /*
- * Access the _thread_dfl_count array under the protection of signal
- * deferral.
- */
- _thread_kern_sig_defer();
/*
- * Enter a loop to find the signals that are SIG_DFL. For
- * these signals we must install a dummy signal handler in
- * order for the kernel to pass them in to us. POSIX says
- * that the _application_ must explicitly install a dummy
- * handler for signals that are SIG_IGN in order to sigwait
- * on them. Note that SIG_IGN signals are left in the
- * mask because a subsequent sigaction could enable an
- * ignored signal.
+ * All signals are invalid for waiting.
*/
- sigemptyset(&tempset);
- for (i = 1; i < NSIG; i++) {
- if (sigismember(&waitset, i) &&
- (_thread_sigact[i - 1].sa_handler == SIG_DFL)) {
- _thread_dfl_count[i]++;
- sigaddset(&tempset, i);
- if (_thread_dfl_count[i] == 1) {
- if (__sys_sigaction(i,&act,NULL) != 0)
- ret = -1;
- }
- }
- }
- /* Done accessing _thread_dfl_count for now. */
- _thread_kern_sig_undefer();
-
- if (ret == 0) {
- /*
- * Save the wait signal mask. The wait signal
- * mask is independent of the threads signal mask
- * and requires separate storage.
- */
- curthread->data.sigwait = &waitset;
-
- /* Wait for a signal: */
- _thread_kern_sched_state(PS_SIGWAIT, __FILE__, __LINE__);
-
- /* Return the signal number to the caller: */
- *sig = curthread->signo;
-
- /*
- * Probably unnecessary, but since it's in a union struct
- * we don't know how it could be used in the future.
- */
- curthread->data.sigwait = NULL;
- }
-
- /*
- * Access the _thread_dfl_count array under the protection of signal
- * deferral.
- */
- _thread_kern_sig_defer();
-
- /* Restore the sigactions: */
- act.sa_handler = SIG_DFL;
- for (i = 1; i < NSIG; i++) {
- if (sigismember(&tempset, i)) {
- _thread_dfl_count[i]--;
- if ((_thread_sigact[i - 1].sa_handler == SIG_DFL) &&
- (_thread_dfl_count[i] == 0)) {
- if (__sys_sigaction(i,&act,NULL) != 0)
- ret = -1;
- }
- }
- }
- /* Done accessing _thread_dfl_count. */
- _thread_kern_sig_undefer();
-
- _thread_leave_cancellation_point();
-
- /* Return the completion status: */
- return (ret);
+ return (EINVAL);
}
diff --git a/lib/libpthread/thread/thr_wait4.c b/lib/libpthread/thread/thr_wait4.c
index 90df876..07b0c84 100644
--- a/lib/libpthread/thread/thr_wait4.c
+++ b/lib/libpthread/thread/thr_wait4.c
@@ -41,35 +41,6 @@
__weak_reference(__wait4, wait4);
pid_t
-_wait4(pid_t pid, int *istat, int options, struct rusage * rusage)
-{
- struct pthread *curthread = _get_curthread();
- pid_t ret;
-
- _thread_kern_sig_defer();
-
- /* Perform a non-blocking wait4 syscall: */
- while ((ret = __sys_wait4(pid, istat, options | WNOHANG, rusage)) == 0 && (options & WNOHANG) == 0) {
- /* Reset the interrupted operation flag: */
- curthread->interrupted = 0;
-
- /* Schedule the next thread while this one waits: */
- _thread_kern_sched_state(PS_WAIT_WAIT, __FILE__, __LINE__);
-
- /* Check if this call was interrupted by a signal: */
- if (curthread->interrupted) {
- errno = EINTR;
- ret = -1;
- break;
- }
- }
-
- _thread_kern_sig_undefer();
-
- return (ret);
-}
-
-pid_t
__wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
{
pid_t ret;
diff --git a/lib/libpthread/thread/thr_write.c b/lib/libpthread/thread/thr_write.c
index 80925ec..4c8c171 100644
--- a/lib/libpthread/thread/thr_write.c
+++ b/lib/libpthread/thread/thr_write.c
@@ -43,104 +43,12 @@
__weak_reference(__write, write);
ssize_t
-_write(int fd, const void *buf, size_t nbytes)
-{
- struct pthread *curthread = _get_curthread();
- int blocking;
- int type;
- ssize_t n;
- ssize_t num = 0;
- ssize_t ret;
-
- /* POSIX says to do just this: */
- if (nbytes == 0)
- return (0);
-
- /* Lock the file descriptor for write: */
- if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
- /* Get the read/write mode type: */
- type = _thread_fd_getflags(fd) & O_ACCMODE;
-
- /* Check if the file is not open for write: */
- if (type != O_WRONLY && type != O_RDWR) {
- /* File is not open for write: */
- errno = EBADF;
- _FD_UNLOCK(fd, FD_WRITE);
- return (-1);
- }
-
- /* Check if file operations are to block */
- blocking = ((_thread_fd_getflags(fd) & O_NONBLOCK) == 0);
-
- /*
- * Loop while no error occurs and until the expected number
- * of bytes are written if performing a blocking write:
- */
- while (ret == 0) {
- /* Perform a non-blocking write syscall: */
- n = __sys_write(fd, buf + num, nbytes - num);
-
- /* Check if one or more bytes were written: */
- if (n > 0)
- /*
- * Keep a count of the number of bytes
- * written:
- */
- num += n;
-
- /*
- * If performing a blocking write, check if the
- * write would have blocked or if some bytes
- * were written but there are still more to
- * write:
- */
- if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
- errno == EAGAIN)) || (n >= 0 && num < nbytes))) {
- curthread->data.fd.fd = fd;
- _thread_kern_set_timeout(NULL);
-
- /* Reset the interrupted operation flag: */
- curthread->interrupted = 0;
-
- _thread_kern_sched_state(PS_FDW_WAIT,
- __FILE__, __LINE__);
-
- /*
- * Check if the operation was
- * interrupted by a signal
- */
- if (curthread->interrupted) {
- /* Return an error: */
- ret = -1;
- }
-
- /*
- * If performing a non-blocking write or if an
- * error occurred, just return whatever the write
- * syscall did:
- */
- } else if (!blocking || n < 0) {
- /* A non-blocking call might return zero: */
- ret = n;
- break;
-
- /* Check if the write has completed: */
- } else if (num >= nbytes)
- /* Return the number of bytes written: */
- ret = num;
- }
- _FD_UNLOCK(fd, FD_WRITE);
- }
- return (ret);
-}
-
-ssize_t
__write(int fd, const void *buf, size_t nbytes)
{
ssize_t ret;
_thread_enter_cancellation_point();
- ret = _write(fd, buf, nbytes);
+ ret = __sys_write(fd, buf, nbytes);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_writev.c b/lib/libpthread/thread/thr_writev.c
index 4fcb9f1..cff95b1 100644
--- a/lib/libpthread/thread/thr_writev.c
+++ b/lib/libpthread/thread/thr_writev.c
@@ -45,171 +45,12 @@
__weak_reference(__writev, writev);
ssize_t
-_writev(int fd, const struct iovec * iov, int iovcnt)
-{
- struct pthread *curthread = _get_curthread();
- int blocking;
- int idx = 0;
- int type;
- ssize_t cnt;
- ssize_t n;
- ssize_t num = 0;
- ssize_t ret;
- struct iovec liov[20];
- struct iovec *p_iov = liov;
-
- /* Check if the array size exceeds to compiled in size: */
- if (iovcnt > (sizeof(liov) / sizeof(struct iovec))) {
- /* Allocate memory for the local array: */
- if ((p_iov = (struct iovec *)
- malloc(iovcnt * sizeof(struct iovec))) == NULL) {
- /* Insufficient memory: */
- errno = ENOMEM;
- return (-1);
- }
- }
-
- /* Copy the caller's array so that it can be modified locally: */
- memcpy(p_iov,iov,iovcnt * sizeof(struct iovec));
-
- /* Lock the file descriptor for write: */
- if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) {
- /* Get the read/write mode type: */
- type = _thread_fd_getflags(fd) & O_ACCMODE;
-
- /* Check if the file is not open for write: */
- if (type != O_WRONLY && type != O_RDWR) {
- /* File is not open for write: */
- errno = EBADF;
- _FD_UNLOCK(fd, FD_WRITE);
- return (-1);
- }
-
- /* Check if file operations are to block */
- blocking = ((_thread_fd_getflags(fd) & O_NONBLOCK) == 0);
-
- /*
- * Loop while no error occurs and until the expected number
- * of bytes are written if performing a blocking write:
- */
- while (ret == 0) {
- /* Perform a non-blocking write syscall: */
- n = __sys_writev(fd, &p_iov[idx], iovcnt - idx);
-
- /* Check if one or more bytes were written: */
- if (n > 0) {
- /*
- * Keep a count of the number of bytes
- * written:
- */
- num += n;
-
- /*
- * Enter a loop to check if a short write
- * occurred and move the index to the
- * array entry where the short write
- * ended:
- */
- cnt = n;
- while (cnt > 0 && idx < iovcnt) {
- /*
- * If the residual count exceeds
- * the size of this vector, then
- * it was completely written:
- */
- if (cnt >= p_iov[idx].iov_len)
- /*
- * Decrement the residual
- * count and increment the
- * index to the next array
- * entry:
- */
- cnt -= p_iov[idx++].iov_len;
- else {
- /*
- * This entry was only
- * partially written, so
- * adjust it's length
- * and base pointer ready
- * for the next write:
- */
- p_iov[idx].iov_len -= cnt;
- p_iov[idx].iov_base += cnt;
- cnt = 0;
- }
- }
- } else if (n == 0) {
- /*
- * Avoid an infinite loop if the last iov_len is
- * 0.
- */
- while (idx < iovcnt && p_iov[idx].iov_len == 0)
- idx++;
-
- if (idx == iovcnt) {
- ret = num;
- break;
- }
- }
-
- /*
- * If performing a blocking write, check if the
- * write would have blocked or if some bytes
- * were written but there are still more to
- * write:
- */
- if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
- errno == EAGAIN)) || (n >= 0 && idx < iovcnt))) {
- curthread->data.fd.fd = fd;
- _thread_kern_set_timeout(NULL);
-
- /* Reset the interrupted operation flag: */
- curthread->interrupted = 0;
-
- _thread_kern_sched_state(PS_FDW_WAIT,
- __FILE__, __LINE__);
-
- /*
- * Check if the operation was
- * interrupted by a signal
- */
- if (curthread->interrupted) {
- /* Return an error: */
- ret = -1;
- }
-
- /*
- * If performing a non-blocking write or if an
- * error occurred, just return whatever the write
- * syscall did:
- */
- } else if (!blocking || n < 0) {
- /* A non-blocking call might return zero: */
- ret = n;
- break;
-
- /* Check if the write has completed: */
- } else if (idx == iovcnt)
- /* Return the number of bytes written: */
- ret = num;
- }
- _FD_UNLOCK(fd, FD_RDWR);
- }
-
- /* If memory was allocated for the array, free it: */
- if (p_iov != liov)
- free(p_iov);
-
- return (ret);
-}
-
-ssize_t
__writev(int fd, const struct iovec *iov, int iovcnt)
{
ssize_t ret;
_thread_enter_cancellation_point();
- ret = _writev(fd, iov, iovcnt);
+ ret = __sys_writev(fd, iov, iovcnt);
_thread_leave_cancellation_point();
return ret;
diff --git a/lib/libpthread/thread/thr_yield.c b/lib/libpthread/thread/thr_yield.c
index ed66da6..e652a9c 100644
--- a/lib/libpthread/thread/thr_yield.c
+++ b/lib/libpthread/thread/thr_yield.c
@@ -46,7 +46,7 @@ _sched_yield(void)
curthread->slice_usec = -1;
/* Schedule the next thread: */
- _thread_kern_sched(NULL);
+ _thread_kern_sched();
/* Always return no error. */
return(0);
@@ -62,5 +62,5 @@ _pthread_yield(void)
curthread->slice_usec = -1;
/* Schedule the next thread: */
- _thread_kern_sched(NULL);
+ _thread_kern_sched();
}
OpenPOWER on IntegriCloud