diff options
-rw-r--r-- | lib/libc_r/uthread/pthread_private.h | 20 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_cancel.c | 7 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_fd.c | 6 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_file.c | 4 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_init.c | 20 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_kern.c | 4 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_spinlock.c | 4 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_suspend_np.c | 109 | ||||
-rw-r--r-- | lib/libpthread/uthread/pthread_private.h | 20 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_cancel.c | 7 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_fd.c | 6 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_file.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_init.c | 20 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_kern.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_spinlock.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_suspend_np.c | 109 |
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 |