summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc_r/uthread/pthread_private.h7
-rw-r--r--lib/libc_r/uthread/uthread_cond.c55
-rw-r--r--lib/libc_r/uthread/uthread_create.c2
-rw-r--r--lib/libc_r/uthread/uthread_info.c8
-rw-r--r--lib/libc_r/uthread/uthread_init.c16
-rw-r--r--lib/libc_r/uthread/uthread_kern.c21
-rw-r--r--lib/libc_r/uthread/uthread_kill.c20
-rw-r--r--lib/libc_r/uthread/uthread_mutex.c18
-rw-r--r--lib/libc_r/uthread/uthread_spec.c4
-rw-r--r--lib/libpthread/uthread/pthread_private.h7
-rw-r--r--lib/libpthread/uthread/uthread_cond.c55
-rw-r--r--lib/libpthread/uthread/uthread_create.c2
-rw-r--r--lib/libpthread/uthread/uthread_info.c8
-rw-r--r--lib/libpthread/uthread/uthread_init.c16
-rw-r--r--lib/libpthread/uthread/uthread_kern.c21
-rw-r--r--lib/libpthread/uthread/uthread_kill.c20
-rw-r--r--lib/libpthread/uthread/uthread_mutex.c18
-rw-r--r--lib/libpthread/uthread/uthread_spec.c4
18 files changed, 190 insertions, 112 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index 14c20b26691..96d53c36d4e 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -552,7 +552,9 @@ void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void) /* __attribute__((constructor)) */;
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, const char *, int);
+void _thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno);
void _thread_kern_set_timeout(struct timespec *);
void _thread_sig_handler(int, int, struct sigcontext *);
void _thread_start(void);
@@ -564,8 +566,7 @@ int _thread_queue_remove(struct pthread_queue *, struct pthread *);
int _thread_fd_table_init(int fd);
struct pthread *_thread_queue_get(struct pthread_queue *);
struct pthread *_thread_queue_deq(struct pthread_queue *);
-pthread_addr_t _thread_gc(pthread_addr_t);
-
+pthread_addr_t _thread_gc(pthread_addr_t);
/* #include <signal.h> */
#ifdef _USER_SIGNAL_H
diff --git a/lib/libc_r/uthread/uthread_cond.c b/lib/libc_r/uthread/uthread_cond.c
index aedc36b4b31..dd073a32948 100644
--- a/lib/libc_r/uthread/uthread_cond.c
+++ b/lib/libc_r/uthread/uthread_cond.c
@@ -143,6 +143,9 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
switch ((*cond)->c_type) {
/* Fast condition variable: */
case COND_TYPE_FAST:
+ /* Wait forever: */
+ _thread_run->wakeup_time.tv_sec = -1;
+
/*
* Queue the running thread for the condition
* variable:
@@ -150,34 +153,36 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
_thread_queue_enq(&(*cond)->c_queue, _thread_run);
/* Unlock the mutex: */
- pthread_mutex_unlock(mutex);
-
- /* Wait forever: */
- _thread_run->wakeup_time.tv_sec = -1;
-
- /* Unlock the condition variable structure: */
- _SPINUNLOCK(&(*cond)->lock);
-
- /* Schedule the next thread: */
- _thread_kern_sched_state(PS_COND_WAIT,
- __FILE__, __LINE__);
+ if ((rval = pthread_mutex_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove the
+ * running thread from the condition
+ * variable queue:
+ */
+ _thread_queue_deq(&(*cond)->c_queue);
- /* Lock the condition variable structure: */
- _SPINLOCK(&(*cond)->lock);
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /* Schedule the next thread: */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
- /* Lock the mutex: */
- rval = pthread_mutex_lock(mutex);
+ /* Lock the mutex: */
+ rval = pthread_mutex_lock(mutex);
+ }
break;
/* Trap invalid condition variable types: */
default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
/* Return an invalid argument error: */
rval = EINVAL;
break;
}
- /* Unlock the condition variable structure: */
- _SPINUNLOCK(&(*cond)->lock);
}
/* Return the completion status: */
@@ -227,16 +232,13 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
* variable queue:
*/
_thread_queue_deq(&(*cond)->c_queue);
- } else {
+
/* Unlock the condition variable structure: */
_SPINUNLOCK(&(*cond)->lock);
-
+ } else {
/* Schedule the next thread: */
- _thread_kern_sched_state(PS_COND_WAIT,
- __FILE__, __LINE__);
-
- /* Lock the condition variable structure: */
- _SPINLOCK(&(*cond)->lock);
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
/* Lock the mutex: */
if ((rval = pthread_mutex_lock(mutex)) != 0) {
@@ -251,13 +253,14 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
/* Trap invalid condition variable types: */
default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
/* Return an invalid argument error: */
rval = EINVAL;
break;
}
- /* Unlock the condition variable structure: */
- _SPINUNLOCK(&(*cond)->lock);
}
/* Return the completion status: */
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
index 68db603cac2..ce70db0b3d4 100644
--- a/lib/libc_r/uthread/uthread_create.c
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -46,7 +46,7 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
{
int f_gc = 0;
int ret = 0;
- pthread_t gc_thread;
+ pthread_t gc_thread;
pthread_t new_thread;
pthread_attr_t pattr;
void *stack;
diff --git a/lib/libc_r/uthread/uthread_info.c b/lib/libc_r/uthread/uthread_info.c
index 9db574e7521..6a863f9463a 100644
--- a/lib/libc_r/uthread/uthread_info.c
+++ b/lib/libc_r/uthread/uthread_info.c
@@ -96,10 +96,10 @@ _thread_dump_info(void)
/* Output a record for the current thread: */
snprintf(s, sizeof(s),
"--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
- pthread, (pthread->name == NULL) ?
- "":pthread->name, pthread->pthread_priority,
- thread_info[j].name,
- pthread->fname,pthread->lineno);
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->pthread_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
_thread_sys_write(fd, s, strlen(s));
/* Check if this is the running thread: */
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index 95bc34e2797..84148b4f567 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -135,19 +135,19 @@ _thread_init(void)
* Setup a new session for this process which is
* assumed to be running as root.
*/
- if (setsid() == -1)
+ if (setsid() == -1)
PANIC("Can't set session ID");
- if (revoke(_PATH_CONSOLE) != 0)
+ if (revoke(_PATH_CONSOLE) != 0)
PANIC("Can't revoke console");
- if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
+ if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
PANIC("Can't open console");
- if (setlogin("root") == -1)
+ if (setlogin("root") == -1)
PANIC("Can't set login to root");
- if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
+ if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
PANIC("Can't set controlling terminal");
- if (_thread_sys_dup2(fd,0) == -1 ||
- _thread_sys_dup2(fd,1) == -1 ||
- _thread_sys_dup2(fd,2) == -1)
+ if (_thread_sys_dup2(fd,0) == -1 ||
+ _thread_sys_dup2(fd,1) == -1 ||
+ _thread_sys_dup2(fd,2) == -1)
PANIC("Can't dup2");
}
diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c
index f2c54f69a51..6f97c2aac65 100644
--- a/lib/libc_r/uthread/uthread_kern.c
+++ b/lib/libc_r/uthread/uthread_kern.c
@@ -29,8 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: uthread_kern.c,v 1.2 1998/11/09 03:13:20 d Exp $
- * $OpenBSD: uthread_kern.c,v 1.2 1998/11/09 03:13:20 d Exp $
+ * $Id: uthread_kern.c,v 1.3 1998/11/20 12:13:32 d Exp $
+ * $OpenBSD: uthread_kern.c,v 1.3 1998/11/20 12:13:32 d Exp $
*
*/
#include <errno.h>
@@ -574,6 +574,7 @@ _thread_kern_sched(struct sigcontext * scp)
* Do a sigreturn to restart the thread that
* was interrupted by a signal:
*/
+ _thread_kern_in_sched = 0;
_thread_sys_sigreturn(&_thread_run->saved_sigcontext);
} else
/*
@@ -605,6 +606,22 @@ _thread_kern_sched_state(enum pthread_state state, const char *fname, int lineno
return;
}
+void
+_thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno)
+{
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ _SPINUNLOCK(lock);
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
static void
_thread_kern_select(int wait_reqd)
{
diff --git a/lib/libc_r/uthread/uthread_kill.c b/lib/libc_r/uthread/uthread_kill.c
index 292ba5caf8f..5c3f98d441b 100644
--- a/lib/libc_r/uthread/uthread_kill.c
+++ b/lib/libc_r/uthread/uthread_kill.c
@@ -83,6 +83,26 @@ pthread_kill(pthread_t pthread, int sig)
sigaddset(&pthread->sigpend,sig);
break;
+ case PS_SELECT_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_SLEEP_WAIT:
+ if (!sigismember(&pthread->sigmask, sig) &&
+ (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else {
+ /* Increment the pending signal count: */
+ sigaddset(&pthread->sigpend,sig);
+ }
+ break;
+
default:
/* Increment the pending signal count: */
sigaddset(&pthread->sigpend,sig);
diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c
index 4f4aa8af041..a7e8dfee6b5 100644
--- a/lib/libc_r/uthread/uthread_mutex.c
+++ b/lib/libc_r/uthread/uthread_mutex.c
@@ -257,11 +257,10 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
*/
_thread_queue_enq(&(*mutex)->m_queue, _thread_run);
- /* Unlock the mutex structure: */
- _SPINUNLOCK(&(*mutex)->lock);
-
- /* Block signals: */
- _thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__);
+ /* Wait for the mutex: */
+ _thread_kern_sched_state_unlock(
+ PS_MUTEX_WAIT, &(*mutex)->lock,
+ __FILE__, __LINE__);
/* Lock the mutex again: */
_SPINLOCK(&(*mutex)->lock);
@@ -290,11 +289,10 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
*/
_thread_queue_enq(&(*mutex)->m_queue, _thread_run);
- /* Unlock the mutex structure: */
- _SPINUNLOCK(&(*mutex)->lock);
-
- /* Block signals: */
- _thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__);
+ /* Wait for the mutex: */
+ _thread_kern_sched_state_unlock(
+ PS_MUTEX_WAIT, &(*mutex)->lock,
+ __FILE__, __LINE__);
/* Lock the mutex again: */
_SPINLOCK(&(*mutex)->lock);
diff --git a/lib/libc_r/uthread/uthread_spec.c b/lib/libc_r/uthread/uthread_spec.c
index 1fe789e6201..c5783331063 100644
--- a/lib/libc_r/uthread/uthread_spec.c
+++ b/lib/libc_r/uthread/uthread_spec.c
@@ -95,10 +95,10 @@ _thread_cleanupspecific(void)
for (itr = 0; itr < PTHREAD_DESTRUCTOR_ITERATIONS; itr++) {
for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
if (_thread_run->specific_data_count) {
- destructor = data = NULL;
-
/* Lock the key table entry: */
_SPINLOCK(&key_table[key].lock);
+ destructor = data = NULL;
+
if (key_table[key].allocated) {
if (_thread_run->specific_data[key]) {
data = (void *) _thread_run->specific_data[key];
diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h
index 14c20b26691..96d53c36d4e 100644
--- a/lib/libpthread/uthread/pthread_private.h
+++ b/lib/libpthread/uthread/pthread_private.h
@@ -552,7 +552,9 @@ void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void) /* __attribute__((constructor)) */;
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, const char *, int);
+void _thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno);
void _thread_kern_set_timeout(struct timespec *);
void _thread_sig_handler(int, int, struct sigcontext *);
void _thread_start(void);
@@ -564,8 +566,7 @@ int _thread_queue_remove(struct pthread_queue *, struct pthread *);
int _thread_fd_table_init(int fd);
struct pthread *_thread_queue_get(struct pthread_queue *);
struct pthread *_thread_queue_deq(struct pthread_queue *);
-pthread_addr_t _thread_gc(pthread_addr_t);
-
+pthread_addr_t _thread_gc(pthread_addr_t);
/* #include <signal.h> */
#ifdef _USER_SIGNAL_H
diff --git a/lib/libpthread/uthread/uthread_cond.c b/lib/libpthread/uthread/uthread_cond.c
index aedc36b4b31..dd073a32948 100644
--- a/lib/libpthread/uthread/uthread_cond.c
+++ b/lib/libpthread/uthread/uthread_cond.c
@@ -143,6 +143,9 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
switch ((*cond)->c_type) {
/* Fast condition variable: */
case COND_TYPE_FAST:
+ /* Wait forever: */
+ _thread_run->wakeup_time.tv_sec = -1;
+
/*
* Queue the running thread for the condition
* variable:
@@ -150,34 +153,36 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
_thread_queue_enq(&(*cond)->c_queue, _thread_run);
/* Unlock the mutex: */
- pthread_mutex_unlock(mutex);
-
- /* Wait forever: */
- _thread_run->wakeup_time.tv_sec = -1;
-
- /* Unlock the condition variable structure: */
- _SPINUNLOCK(&(*cond)->lock);
-
- /* Schedule the next thread: */
- _thread_kern_sched_state(PS_COND_WAIT,
- __FILE__, __LINE__);
+ if ((rval = pthread_mutex_unlock(mutex)) != 0) {
+ /*
+ * Cannot unlock the mutex, so remove the
+ * running thread from the condition
+ * variable queue:
+ */
+ _thread_queue_deq(&(*cond)->c_queue);
- /* Lock the condition variable structure: */
- _SPINLOCK(&(*cond)->lock);
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+ } else {
+ /* Schedule the next thread: */
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
- /* Lock the mutex: */
- rval = pthread_mutex_lock(mutex);
+ /* Lock the mutex: */
+ rval = pthread_mutex_lock(mutex);
+ }
break;
/* Trap invalid condition variable types: */
default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
/* Return an invalid argument error: */
rval = EINVAL;
break;
}
- /* Unlock the condition variable structure: */
- _SPINUNLOCK(&(*cond)->lock);
}
/* Return the completion status: */
@@ -227,16 +232,13 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
* variable queue:
*/
_thread_queue_deq(&(*cond)->c_queue);
- } else {
+
/* Unlock the condition variable structure: */
_SPINUNLOCK(&(*cond)->lock);
-
+ } else {
/* Schedule the next thread: */
- _thread_kern_sched_state(PS_COND_WAIT,
- __FILE__, __LINE__);
-
- /* Lock the condition variable structure: */
- _SPINLOCK(&(*cond)->lock);
+ _thread_kern_sched_state_unlock(PS_COND_WAIT,
+ &(*cond)->lock, __FILE__, __LINE__);
/* Lock the mutex: */
if ((rval = pthread_mutex_lock(mutex)) != 0) {
@@ -251,13 +253,14 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
/* Trap invalid condition variable types: */
default:
+ /* Unlock the condition variable structure: */
+ _SPINUNLOCK(&(*cond)->lock);
+
/* Return an invalid argument error: */
rval = EINVAL;
break;
}
- /* Unlock the condition variable structure: */
- _SPINUNLOCK(&(*cond)->lock);
}
/* Return the completion status: */
diff --git a/lib/libpthread/uthread/uthread_create.c b/lib/libpthread/uthread/uthread_create.c
index 68db603cac2..ce70db0b3d4 100644
--- a/lib/libpthread/uthread/uthread_create.c
+++ b/lib/libpthread/uthread/uthread_create.c
@@ -46,7 +46,7 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
{
int f_gc = 0;
int ret = 0;
- pthread_t gc_thread;
+ pthread_t gc_thread;
pthread_t new_thread;
pthread_attr_t pattr;
void *stack;
diff --git a/lib/libpthread/uthread/uthread_info.c b/lib/libpthread/uthread/uthread_info.c
index 9db574e7521..6a863f9463a 100644
--- a/lib/libpthread/uthread/uthread_info.c
+++ b/lib/libpthread/uthread/uthread_info.c
@@ -96,10 +96,10 @@ _thread_dump_info(void)
/* Output a record for the current thread: */
snprintf(s, sizeof(s),
"--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
- pthread, (pthread->name == NULL) ?
- "":pthread->name, pthread->pthread_priority,
- thread_info[j].name,
- pthread->fname,pthread->lineno);
+ pthread, (pthread->name == NULL) ?
+ "":pthread->name, pthread->pthread_priority,
+ thread_info[j].name,
+ pthread->fname,pthread->lineno);
_thread_sys_write(fd, s, strlen(s));
/* Check if this is the running thread: */
diff --git a/lib/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c
index 95bc34e2797..84148b4f567 100644
--- a/lib/libpthread/uthread/uthread_init.c
+++ b/lib/libpthread/uthread/uthread_init.c
@@ -135,19 +135,19 @@ _thread_init(void)
* Setup a new session for this process which is
* assumed to be running as root.
*/
- if (setsid() == -1)
+ if (setsid() == -1)
PANIC("Can't set session ID");
- if (revoke(_PATH_CONSOLE) != 0)
+ if (revoke(_PATH_CONSOLE) != 0)
PANIC("Can't revoke console");
- if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
+ if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
PANIC("Can't open console");
- if (setlogin("root") == -1)
+ if (setlogin("root") == -1)
PANIC("Can't set login to root");
- if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
+ if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1)
PANIC("Can't set controlling terminal");
- if (_thread_sys_dup2(fd,0) == -1 ||
- _thread_sys_dup2(fd,1) == -1 ||
- _thread_sys_dup2(fd,2) == -1)
+ if (_thread_sys_dup2(fd,0) == -1 ||
+ _thread_sys_dup2(fd,1) == -1 ||
+ _thread_sys_dup2(fd,2) == -1)
PANIC("Can't dup2");
}
diff --git a/lib/libpthread/uthread/uthread_kern.c b/lib/libpthread/uthread/uthread_kern.c
index f2c54f69a51..6f97c2aac65 100644
--- a/lib/libpthread/uthread/uthread_kern.c
+++ b/lib/libpthread/uthread/uthread_kern.c
@@ -29,8 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: uthread_kern.c,v 1.2 1998/11/09 03:13:20 d Exp $
- * $OpenBSD: uthread_kern.c,v 1.2 1998/11/09 03:13:20 d Exp $
+ * $Id: uthread_kern.c,v 1.3 1998/11/20 12:13:32 d Exp $
+ * $OpenBSD: uthread_kern.c,v 1.3 1998/11/20 12:13:32 d Exp $
*
*/
#include <errno.h>
@@ -574,6 +574,7 @@ _thread_kern_sched(struct sigcontext * scp)
* Do a sigreturn to restart the thread that
* was interrupted by a signal:
*/
+ _thread_kern_in_sched = 0;
_thread_sys_sigreturn(&_thread_run->saved_sigcontext);
} else
/*
@@ -605,6 +606,22 @@ _thread_kern_sched_state(enum pthread_state state, const char *fname, int lineno
return;
}
+void
+_thread_kern_sched_state_unlock(enum pthread_state state,
+ spinlock_t *lock, char *fname, int lineno)
+{
+ /* Change the state of the current thread: */
+ _thread_run->state = state;
+ _thread_run->fname = fname;
+ _thread_run->lineno = lineno;
+
+ _SPINUNLOCK(lock);
+
+ /* Schedule the next thread that is ready: */
+ _thread_kern_sched(NULL);
+ return;
+}
+
static void
_thread_kern_select(int wait_reqd)
{
diff --git a/lib/libpthread/uthread/uthread_kill.c b/lib/libpthread/uthread/uthread_kill.c
index 292ba5caf8f..5c3f98d441b 100644
--- a/lib/libpthread/uthread/uthread_kill.c
+++ b/lib/libpthread/uthread/uthread_kill.c
@@ -83,6 +83,26 @@ pthread_kill(pthread_t pthread, int sig)
sigaddset(&pthread->sigpend,sig);
break;
+ case PS_SELECT_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ case PS_SLEEP_WAIT:
+ if (!sigismember(&pthread->sigmask, sig) &&
+ (_thread_sigact[sig - 1].sa_handler != SIG_IGN)) {
+ /* Flag the operation as interrupted: */
+ pthread->interrupted = 1;
+
+ /* Change the state of the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+
+ /* Return the signal number: */
+ pthread->signo = sig;
+ } else {
+ /* Increment the pending signal count: */
+ sigaddset(&pthread->sigpend,sig);
+ }
+ break;
+
default:
/* Increment the pending signal count: */
sigaddset(&pthread->sigpend,sig);
diff --git a/lib/libpthread/uthread/uthread_mutex.c b/lib/libpthread/uthread/uthread_mutex.c
index 4f4aa8af041..a7e8dfee6b5 100644
--- a/lib/libpthread/uthread/uthread_mutex.c
+++ b/lib/libpthread/uthread/uthread_mutex.c
@@ -257,11 +257,10 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
*/
_thread_queue_enq(&(*mutex)->m_queue, _thread_run);
- /* Unlock the mutex structure: */
- _SPINUNLOCK(&(*mutex)->lock);
-
- /* Block signals: */
- _thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__);
+ /* Wait for the mutex: */
+ _thread_kern_sched_state_unlock(
+ PS_MUTEX_WAIT, &(*mutex)->lock,
+ __FILE__, __LINE__);
/* Lock the mutex again: */
_SPINLOCK(&(*mutex)->lock);
@@ -290,11 +289,10 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
*/
_thread_queue_enq(&(*mutex)->m_queue, _thread_run);
- /* Unlock the mutex structure: */
- _SPINUNLOCK(&(*mutex)->lock);
-
- /* Block signals: */
- _thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__);
+ /* Wait for the mutex: */
+ _thread_kern_sched_state_unlock(
+ PS_MUTEX_WAIT, &(*mutex)->lock,
+ __FILE__, __LINE__);
/* Lock the mutex again: */
_SPINLOCK(&(*mutex)->lock);
diff --git a/lib/libpthread/uthread/uthread_spec.c b/lib/libpthread/uthread/uthread_spec.c
index 1fe789e6201..c5783331063 100644
--- a/lib/libpthread/uthread/uthread_spec.c
+++ b/lib/libpthread/uthread/uthread_spec.c
@@ -95,10 +95,10 @@ _thread_cleanupspecific(void)
for (itr = 0; itr < PTHREAD_DESTRUCTOR_ITERATIONS; itr++) {
for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
if (_thread_run->specific_data_count) {
- destructor = data = NULL;
-
/* Lock the key table entry: */
_SPINLOCK(&key_table[key].lock);
+ destructor = data = NULL;
+
if (key_table[key].allocated) {
if (_thread_run->specific_data[key]) {
data = (void *) _thread_run->specific_data[key];