summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc_r/uthread/pthread_private.h20
-rw-r--r--lib/libc_r/uthread/uthread_cancel.c7
-rw-r--r--lib/libc_r/uthread/uthread_fd.c6
-rw-r--r--lib/libc_r/uthread/uthread_file.c4
-rw-r--r--lib/libc_r/uthread/uthread_init.c20
-rw-r--r--lib/libc_r/uthread/uthread_kern.c4
-rw-r--r--lib/libc_r/uthread/uthread_spinlock.c4
-rw-r--r--lib/libc_r/uthread/uthread_suspend_np.c109
-rw-r--r--lib/libpthread/uthread/pthread_private.h20
-rw-r--r--lib/libpthread/uthread/uthread_cancel.c7
-rw-r--r--lib/libpthread/uthread/uthread_fd.c6
-rw-r--r--lib/libpthread/uthread/uthread_file.c4
-rw-r--r--lib/libpthread/uthread/uthread_init.c20
-rw-r--r--lib/libpthread/uthread/uthread_kern.c4
-rw-r--r--lib/libpthread/uthread/uthread_spinlock.c4
-rw-r--r--lib/libpthread/uthread/uthread_suspend_np.c109
16 files changed, 262 insertions, 86 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index e0436a477ea..3d38ad4c668 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_private.h,v 1.25 2001/08/29 18:33:54 fgsch Exp $ */
+/* $OpenBSD: pthread_private.h,v 1.26 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -646,12 +646,6 @@ struct pthread {
long slice_usec;
/*
- * Incremental priority accumulated by thread while it is ready to
- * run but is denied being run.
- */
- int inc_prio;
-
- /*
* Time to wake up thread. This is used for sleeping threads and
* for any operation which may time out (such as select).
*/
@@ -879,9 +873,6 @@ SCLASS unsigned int volatile _sched_ticks
;
#endif
-/* Last time that an incremental priority update was performed: */
-extern struct timeval kern_inc_prio_time;
-
/* Dead threads: */
SCLASS _thread_list_t _dead_list
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -985,6 +976,13 @@ SCLASS pthread_cond_t _gc_cond
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];
+
+/*
* Scheduling queues:
*/
SCLASS pq_queue_t _readyq;
@@ -1069,7 +1067,7 @@ void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void);
void _thread_kern_sched(struct sigcontext *);
-void _thread_kern_sched_state(enum pthread_state,const char *fname,int lineno);
+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 *);
diff --git a/lib/libc_r/uthread/uthread_cancel.c b/lib/libc_r/uthread/uthread_cancel.c
index 7428ee07ecb..7b157c2b53e 100644
--- a/lib/libc_r/uthread/uthread_cancel.c
+++ b/lib/libc_r/uthread/uthread_cancel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_cancel.c,v 1.3 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_cancel.c,v 1.4 2001/08/30 07:40:47 fgsch Exp $ */
/*
* David Leonard <d@openbsd.org>, 1999. Public domain.
*/
@@ -12,7 +12,10 @@ pthread_cancel(pthread)
{
int ret;
- if ((ret = _find_thread(pthread))) {
+ if ((ret = _find_thread(pthread)) != 0) {
+ /* NOTHING */
+ } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) {
+ ret = 0;
} else if ((pthread->flags & PTHREAD_FLAGS_CANCELED) == 0) {
/* Set the thread's I've-been-cancelled flag: */
pthread->flags |= PTHREAD_FLAGS_CANCELED;
diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c
index b49a3cda8fb..519ba114fc3 100644
--- a/lib/libc_r/uthread/uthread_fd.c
+++ b/lib/libc_r/uthread/uthread_fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_fd.c,v 1.7 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_fd.c,v 1.8 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -453,7 +453,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
}
void
-_thread_fd_unlock_debug(int fd, int lock_type, const char *fname, int lineno)
+_thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
int ret;
@@ -577,7 +577,7 @@ _thread_fd_unlock_debug(int fd, int lock_type, const char *fname, int lineno)
int
_thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
- const char *fname, int lineno)
+ char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
int ret;
diff --git a/lib/libc_r/uthread/uthread_file.c b/lib/libc_r/uthread/uthread_file.c
index bcdecff65e2..41815aeeac8 100644
--- a/lib/libc_r/uthread/uthread_file.c
+++ b/lib/libc_r/uthread/uthread_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_file.c,v 1.5 2000/01/06 07:17:01 d Exp $ */
+/* $OpenBSD: uthread_file.c,v 1.6 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -180,7 +180,7 @@ do_lock(int idx, FILE *fp)
}
void
-_flockfile_debug(FILE * fp, const char *fname, int lineno)
+_flockfile_debug(FILE * fp, char *fname, int lineno)
{
int idx = file_idx(fp);
struct file_lock *p;
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index edf87469bd0..dec4cdace6d 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_init.c,v 1.13 2001/08/29 18:33:54 fgsch Exp $ */
+/* $OpenBSD: uthread_init.c,v 1.14 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -57,7 +57,6 @@
#include "pthread_private.h"
/* Global thread variables. */
-struct timeval kern_inc_prio_time = { 0, 0 };
_stack_list_t _stackq;
extern int _thread_autoinit_dummy_decl;
@@ -175,6 +174,10 @@ _thread_init(void)
*/
_thread_initial->magic = PTHREAD_MAGIC;
+ /* Set the initial cancel state */
+ _thread_initial->cancelstate = PTHREAD_CANCEL_ENABLE;
+ _thread_initial->canceltype = PTHREAD_CANCEL_DEFERRED;
+
/* Default the priority of the initial thread: */
_thread_initial->base_priority = PTHREAD_DEFAULT_PRIORITY;
_thread_initial->active_priority = PTHREAD_DEFAULT_PRIORITY;
@@ -204,12 +207,10 @@ _thread_init(void)
_thread_initial->cleanup = NULL;
_thread_initial->flags = 0;
_thread_initial->error = 0;
- _thread_initial->cancelstate = PTHREAD_CANCEL_ENABLE;
- _thread_initial->canceltype = PTHREAD_CANCEL_DEFERRED;
_SPINLOCK_INIT(&_thread_initial->lock);
TAILQ_INIT(&_thread_list);
TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
- _thread_run = _thread_initial;
+ _set_curthread(_thread_initial);
/* Initialise the global signal action structure: */
sigfillset(&act.sa_mask);
@@ -227,13 +228,16 @@ _thread_init(void)
/* Get the signal handler details: */
else if (_thread_sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
+ &_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;
}
/*
@@ -308,10 +312,6 @@ _thread_init(void)
pthread_cond_init(&_gc_cond,NULL) != 0)
PANIC("Failed to initialise garbage collector mutex or condvar");
- gettimeofday(&kern_inc_prio_time, NULL);
-
_thread_autoinit_dummy_decl = 0;
-
- return;
}
#endif
diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c
index 2376af06534..626a8004b5f 100644
--- a/lib/libc_r/uthread/uthread_kern.c
+++ b/lib/libc_r/uthread/uthread_kern.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_kern.c,v 1.13 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_kern.c,v 1.14 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -579,7 +579,7 @@ _thread_kern_sched(struct sigcontext * scp)
}
void
-_thread_kern_sched_state(enum pthread_state state, const char *fname, int lineno)
+_thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
diff --git a/lib/libc_r/uthread/uthread_spinlock.c b/lib/libc_r/uthread/uthread_spinlock.c
index 418ddcf3427..c958c463383 100644
--- a/lib/libc_r/uthread/uthread_spinlock.c
+++ b/lib/libc_r/uthread/uthread_spinlock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_spinlock.c,v 1.8 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_spinlock.c,v 1.9 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -79,7 +79,7 @@ _spinlock(spinlock_t *lck)
* returning.
*/
void
-_spinlock_debug(spinlock_t *lck, const char *fname, int lineno)
+_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
int cnt = 0;
diff --git a/lib/libc_r/uthread/uthread_suspend_np.c b/lib/libc_r/uthread/uthread_suspend_np.c
index 8c455e0a11d..1758766fecf 100644
--- a/lib/libc_r/uthread/uthread_suspend_np.c
+++ b/lib/libc_r/uthread/uthread_suspend_np.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_suspend_np.c,v 1.4 1999/11/25 07:01:46 d Exp $ */
+/* $OpenBSD: uthread_suspend_np.c,v 1.5 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -37,6 +37,8 @@
#include <pthread.h>
#include "pthread_private.h"
+static void finish_suspension(void *arg);
+
/* Suspend a thread: */
int
pthread_suspend_np(pthread_t thread)
@@ -45,22 +47,98 @@ pthread_suspend_np(pthread_t thread)
/* Find the thread in the list of active threads: */
if ((ret = _find_thread(thread)) == 0) {
- /* The thread exists. Is it running? */
- if (thread->state != PS_RUNNING &&
- thread->state != PS_SUSPENDED) {
- /* The thread operation has been interrupted */
- _thread_seterrno(thread,EINTR);
- thread->interrupted = 1;
- }
-
/*
* Defer signals to protect the scheduling queues from
* access by the signal handler:
*/
_thread_kern_sig_defer();
- /* Suspend the thread. */
- PTHREAD_NEW_STATE(thread,PS_SUSPENDED);
+ switch (thread->state) {
+ case PS_RUNNING:
+ /*
+ * Remove the thread from the priority queue and
+ * set the state to suspended:
+ */
+ PTHREAD_PRIOQ_REMOVE(thread);
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ 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
+ * and mark the operation as interrupted:
+ */
+ if ((thread->flags & PTHREAD_FLAGS_IN_WORKQ) != 0)
+ PTHREAD_WORKQ_REMOVE(thread);
+ _thread_seterrno(thread, EINTR);
+
+ /* FALLTHROUGH */
+ case PS_SLEEP_WAIT:
+ thread->interrupted = 1;
+
+ /* FALLTHROUGH */
+ case PS_SIGTHREAD:
+ case PS_WAIT_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGWAIT:
+ /*
+ * Remove these threads from the waiting queue and
+ * set their state to suspended:
+ */
+ PTHREAD_WAITQ_REMOVE(thread);
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ break;
+
+ case PS_MUTEX_WAIT:
+ /* Mark the thread as suspended and still in a queue. */
+ thread->suspended = SUSP_MUTEX_WAIT;
+
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ break;
+ case PS_COND_WAIT:
+ /* Mark the thread as suspended and still in a queue. */
+ thread->suspended = SUSP_COND_WAIT;
+
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ break;
+ case PS_JOIN:
+ /* Mark the thread as suspended and joining: */
+ thread->suspended = SUSP_JOIN;
+
+ PTHREAD_NEW_STATE(thread, PS_SUSPENDED);
+ break;
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ /* Mark the thread as suspended: */
+ thread->suspended = SUSP_YES;
+
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * set the state to running. When the thread
+ * resumes, it will remove itself from the queue
+ * and call the suspension completion routine.
+ */
+ thread->interrupted = 1;
+ _thread_seterrno(thread, EINTR);
+ PTHREAD_NEW_STATE(thread, PS_RUNNING);
+ thread->continuation = finish_suspension;
+ break;
+
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_STATE_MAX:
+ case PS_SUSPENDED:
+ /* Nothing needs to be done: */
+ break;
+ }
/*
* Undefer and handle pending signals, yielding if
@@ -70,4 +148,13 @@ pthread_suspend_np(pthread_t thread)
}
return(ret);
}
+
+static void
+finish_suspension(void *arg)
+{
+ struct pthread *curthread = _get_curthread();
+
+ if (curthread->suspended != SUSP_NO)
+ _thread_kern_sched_state(PS_SUSPENDED, __FILE__, __LINE__);
+}
#endif
diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h
index e0436a477ea..3d38ad4c668 100644
--- a/lib/libpthread/uthread/pthread_private.h
+++ b/lib/libpthread/uthread/pthread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_private.h,v 1.25 2001/08/29 18:33:54 fgsch Exp $ */
+/* $OpenBSD: pthread_private.h,v 1.26 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -646,12 +646,6 @@ struct pthread {
long slice_usec;
/*
- * Incremental priority accumulated by thread while it is ready to
- * run but is denied being run.
- */
- int inc_prio;
-
- /*
* Time to wake up thread. This is used for sleeping threads and
* for any operation which may time out (such as select).
*/
@@ -879,9 +873,6 @@ SCLASS unsigned int volatile _sched_ticks
;
#endif
-/* Last time that an incremental priority update was performed: */
-extern struct timeval kern_inc_prio_time;
-
/* Dead threads: */
SCLASS _thread_list_t _dead_list
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -985,6 +976,13 @@ SCLASS pthread_cond_t _gc_cond
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];
+
+/*
* Scheduling queues:
*/
SCLASS pq_queue_t _readyq;
@@ -1069,7 +1067,7 @@ void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void);
void _thread_kern_sched(struct sigcontext *);
-void _thread_kern_sched_state(enum pthread_state,const char *fname,int lineno);
+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 *);
diff --git a/lib/libpthread/uthread/uthread_cancel.c b/lib/libpthread/uthread/uthread_cancel.c
index 7428ee07ecb..7b157c2b53e 100644
--- a/lib/libpthread/uthread/uthread_cancel.c
+++ b/lib/libpthread/uthread/uthread_cancel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_cancel.c,v 1.3 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_cancel.c,v 1.4 2001/08/30 07:40:47 fgsch Exp $ */
/*
* David Leonard <d@openbsd.org>, 1999. Public domain.
*/
@@ -12,7 +12,10 @@ pthread_cancel(pthread)
{
int ret;
- if ((ret = _find_thread(pthread))) {
+ if ((ret = _find_thread(pthread)) != 0) {
+ /* NOTHING */
+ } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) {
+ ret = 0;
} else if ((pthread->flags & PTHREAD_FLAGS_CANCELED) == 0) {
/* Set the thread's I've-been-cancelled flag: */
pthread->flags |= PTHREAD_FLAGS_CANCELED;
diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c
index b49a3cda8fb..519ba114fc3 100644
--- a/lib/libpthread/uthread/uthread_fd.c
+++ b/lib/libpthread/uthread/uthread_fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_fd.c,v 1.7 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_fd.c,v 1.8 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -453,7 +453,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
}
void
-_thread_fd_unlock_debug(int fd, int lock_type, const char *fname, int lineno)
+_thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
int ret;
@@ -577,7 +577,7 @@ _thread_fd_unlock_debug(int fd, int lock_type, const char *fname, int lineno)
int
_thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
- const char *fname, int lineno)
+ char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
int ret;
diff --git a/lib/libpthread/uthread/uthread_file.c b/lib/libpthread/uthread/uthread_file.c
index bcdecff65e2..41815aeeac8 100644
--- a/lib/libpthread/uthread/uthread_file.c
+++ b/lib/libpthread/uthread/uthread_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_file.c,v 1.5 2000/01/06 07:17:01 d Exp $ */
+/* $OpenBSD: uthread_file.c,v 1.6 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -180,7 +180,7 @@ do_lock(int idx, FILE *fp)
}
void
-_flockfile_debug(FILE * fp, const char *fname, int lineno)
+_flockfile_debug(FILE * fp, char *fname, int lineno)
{
int idx = file_idx(fp);
struct file_lock *p;
diff --git a/lib/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c
index edf87469bd0..dec4cdace6d 100644
--- a/lib/libpthread/uthread/uthread_init.c
+++ b/lib/libpthread/uthread/uthread_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_init.c,v 1.13 2001/08/29 18:33:54 fgsch Exp $ */
+/* $OpenBSD: uthread_init.c,v 1.14 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -57,7 +57,6 @@
#include "pthread_private.h"
/* Global thread variables. */
-struct timeval kern_inc_prio_time = { 0, 0 };
_stack_list_t _stackq;
extern int _thread_autoinit_dummy_decl;
@@ -175,6 +174,10 @@ _thread_init(void)
*/
_thread_initial->magic = PTHREAD_MAGIC;
+ /* Set the initial cancel state */
+ _thread_initial->cancelstate = PTHREAD_CANCEL_ENABLE;
+ _thread_initial->canceltype = PTHREAD_CANCEL_DEFERRED;
+
/* Default the priority of the initial thread: */
_thread_initial->base_priority = PTHREAD_DEFAULT_PRIORITY;
_thread_initial->active_priority = PTHREAD_DEFAULT_PRIORITY;
@@ -204,12 +207,10 @@ _thread_init(void)
_thread_initial->cleanup = NULL;
_thread_initial->flags = 0;
_thread_initial->error = 0;
- _thread_initial->cancelstate = PTHREAD_CANCEL_ENABLE;
- _thread_initial->canceltype = PTHREAD_CANCEL_DEFERRED;
_SPINLOCK_INIT(&_thread_initial->lock);
TAILQ_INIT(&_thread_list);
TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle);
- _thread_run = _thread_initial;
+ _set_curthread(_thread_initial);
/* Initialise the global signal action structure: */
sigfillset(&act.sa_mask);
@@ -227,13 +228,16 @@ _thread_init(void)
/* Get the signal handler details: */
else if (_thread_sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
+ &_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;
}
/*
@@ -308,10 +312,6 @@ _thread_init(void)
pthread_cond_init(&_gc_cond,NULL) != 0)
PANIC("Failed to initialise garbage collector mutex or condvar");
- gettimeofday(&kern_inc_prio_time, NULL);
-
_thread_autoinit_dummy_decl = 0;
-
- return;
}
#endif
diff --git a/lib/libpthread/uthread/uthread_kern.c b/lib/libpthread/uthread/uthread_kern.c
index 2376af06534..626a8004b5f 100644
--- a/lib/libpthread/uthread/uthread_kern.c
+++ b/lib/libpthread/uthread/uthread_kern.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_kern.c,v 1.13 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_kern.c,v 1.14 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -579,7 +579,7 @@ _thread_kern_sched(struct sigcontext * scp)
}
void
-_thread_kern_sched_state(enum pthread_state state, const char *fname, int lineno)
+_thread_kern_sched_state(enum pthread_state state, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
diff --git a/lib/libpthread/uthread/uthread_spinlock.c b/lib/libpthread/uthread/uthread_spinlock.c
index 418ddcf3427..c958c463383 100644
--- a/lib/libpthread/uthread/uthread_spinlock.c
+++ b/lib/libpthread/uthread/uthread_spinlock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_spinlock.c,v 1.8 2001/08/21 19:24:53 fgsch Exp $ */
+/* $OpenBSD: uthread_spinlock.c,v 1.9 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -79,7 +79,7 @@ _spinlock(spinlock_t *lck)
* returning.
*/
void
-_spinlock_debug(spinlock_t *lck, const char *fname, int lineno)
+_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
int cnt = 0;
diff --git a/lib/libpthread/uthread/uthread_suspend_np.c b/lib/libpthread/uthread/uthread_suspend_np.c
index 8c455e0a11d..1758766fecf 100644
--- a/lib/libpthread/uthread/uthread_suspend_np.c
+++ b/lib/libpthread/uthread/uthread_suspend_np.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_suspend_np.c,v 1.4 1999/11/25 07:01:46 d Exp $ */
+/* $OpenBSD: uthread_suspend_np.c,v 1.5 2001/08/30 07:40:47 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -37,6 +37,8 @@
#include <pthread.h>
#include "pthread_private.h"
+static void finish_suspension(void *arg);
+
/* Suspend a thread: */
int
pthread_suspend_np(pthread_t thread)
@@ -45,22 +47,98 @@ pthread_suspend_np(pthread_t thread)
/* Find the thread in the list of active threads: */
if ((ret = _find_thread(thread)) == 0) {
- /* The thread exists. Is it running? */
- if (thread->state != PS_RUNNING &&
- thread->state != PS_SUSPENDED) {
- /* The thread operation has been interrupted */
- _thread_seterrno(thread,EINTR);
- thread->interrupted = 1;
- }
-
/*
* Defer signals to protect the scheduling queues from
* access by the signal handler:
*/
_thread_kern_sig_defer();
- /* Suspend the thread. */
- PTHREAD_NEW_STATE(thread,PS_SUSPENDED);
+ switch (thread->state) {
+ case PS_RUNNING:
+ /*
+ * Remove the thread from the priority queue and
+ * set the state to suspended:
+ */
+ PTHREAD_PRIOQ_REMOVE(thread);
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ 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
+ * and mark the operation as interrupted:
+ */
+ if ((thread->flags & PTHREAD_FLAGS_IN_WORKQ) != 0)
+ PTHREAD_WORKQ_REMOVE(thread);
+ _thread_seterrno(thread, EINTR);
+
+ /* FALLTHROUGH */
+ case PS_SLEEP_WAIT:
+ thread->interrupted = 1;
+
+ /* FALLTHROUGH */
+ case PS_SIGTHREAD:
+ case PS_WAIT_WAIT:
+ case PS_SIGSUSPEND:
+ case PS_SIGWAIT:
+ /*
+ * Remove these threads from the waiting queue and
+ * set their state to suspended:
+ */
+ PTHREAD_WAITQ_REMOVE(thread);
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ break;
+
+ case PS_MUTEX_WAIT:
+ /* Mark the thread as suspended and still in a queue. */
+ thread->suspended = SUSP_MUTEX_WAIT;
+
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ break;
+ case PS_COND_WAIT:
+ /* Mark the thread as suspended and still in a queue. */
+ thread->suspended = SUSP_COND_WAIT;
+
+ PTHREAD_SET_STATE(thread, PS_SUSPENDED);
+ break;
+ case PS_JOIN:
+ /* Mark the thread as suspended and joining: */
+ thread->suspended = SUSP_JOIN;
+
+ PTHREAD_NEW_STATE(thread, PS_SUSPENDED);
+ break;
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ /* Mark the thread as suspended: */
+ thread->suspended = SUSP_YES;
+
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * set the state to running. When the thread
+ * resumes, it will remove itself from the queue
+ * and call the suspension completion routine.
+ */
+ thread->interrupted = 1;
+ _thread_seterrno(thread, EINTR);
+ PTHREAD_NEW_STATE(thread, PS_RUNNING);
+ thread->continuation = finish_suspension;
+ break;
+
+ case PS_DEAD:
+ case PS_DEADLOCK:
+ case PS_STATE_MAX:
+ case PS_SUSPENDED:
+ /* Nothing needs to be done: */
+ break;
+ }
/*
* Undefer and handle pending signals, yielding if
@@ -70,4 +148,13 @@ pthread_suspend_np(pthread_t thread)
}
return(ret);
}
+
+static void
+finish_suspension(void *arg)
+{
+ struct pthread *curthread = _get_curthread();
+
+ if (curthread->suspended != SUSP_NO)
+ _thread_kern_sched_state(PS_SUSPENDED, __FILE__, __LINE__);
+}
#endif