summaryrefslogtreecommitdiff
path: root/lib/libc_r/uthread
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>2000-10-04 05:55:36 +0000
committerDavid Leonard <d@cvs.openbsd.org>2000-10-04 05:55:36 +0000
commit8e95e2f842b2fdd99c416cc00a8d321656fea5af (patch)
treeae270251a663e179dd260f976e6b3ecb477678cf /lib/libc_r/uthread
parent367c0082943cc6fa224d021a045222f13f86cfe4 (diff)
switch to _machdep_switch() instead of setjmp/longjmp. For some reason this fixes sparc threads.
Diffstat (limited to 'lib/libc_r/uthread')
-rw-r--r--lib/libc_r/uthread/pthread_private.h24
-rw-r--r--lib/libc_r/uthread/uthread_create.c15
-rw-r--r--lib/libc_r/uthread/uthread_kern.c60
3 files changed, 51 insertions, 48 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index 1d2cf83b02c..9cfcffd5ca2 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.19 2000/01/06 07:13:56 d Exp $ */
+/* $OpenBSD: pthread_private.h,v 1.20 2000/10/04 05:55:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -41,7 +41,6 @@
/*
* Include files.
*/
-#include <setjmp.h>
#include <signal.h>
#include <sys/queue.h>
#include <sys/types.h>
@@ -513,16 +512,10 @@ struct pthread {
*/
struct sigcontext saved_sigcontext;
- /*
- * Saved jump buffer used in call to longjmp by _thread_kern_sched
- * if sig_saved is FALSE.
- */
- _machdep_jmp_buf saved_jmp_buf;
-
/*
- * Further machine-dependent context, valid if sig_saved is FALSE.
+ * Machine-dependent context, valid if sig_saved is FALSE.
*/
- struct _machdep_struct _machdep;
+ struct _machdep_state _machdep;
/*
* TRUE if the last state saved was a signal context. FALSE if the
@@ -690,6 +683,16 @@ struct pthread {
};
/*
+ * Flags and prototypes for the machine dependent layer
+ */
+void _thread_machdep_switch(struct _machdep_state *newstate,
+ struct _machdep_state *savestate);
+void _thread_machdep_init(struct _machdep_state *state, void *stackbase,
+ int stacksize, void (*entry)(void));
+void _thread_machdep_save_float_state(struct _machdep_state* statep);
+void _thread_machdep_restore_float_state(struct _machdep_state* statep);
+
+/*
* Global variables for the uthread kernel.
*/
@@ -848,6 +851,7 @@ int _thread_slow_atomic_is_locked(volatile _spinlock_lock_t *);
struct stack * _thread_stack_alloc(void *, size_t);
void _thread_stack_free(struct stack *);
+
/* #include <signal.h> */
#ifdef _USER_SIGNAL_H
int _thread_sys_kill(pid_t, int);
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
index 3a9499d0a1c..a1981e90f3c 100644
--- a/lib/libc_r/uthread/uthread_create.c
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_create.c,v 1.13 2000/01/06 07:15:05 d Exp $ */
+/* $OpenBSD: uthread_create.c,v 1.14 2000/10/04 05:55:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -104,16 +104,13 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
/* Initialise the thread for signals: */
new_thread->sigmask = _thread_run->sigmask;
- /* Initialise the jump buffer: */
- _thread_machdep_setjmp(new_thread->saved_jmp_buf);
-
/*
- * Set up new stack frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * _thread_start().
+ * Set up new stack frame so that it 'returns' to
+ * the beginning of _thread_start() after it is
+ * switched to:
*/
- _thread_machdep_thread_create(new_thread, _thread_start,
- pattr);
+ _thread_machdep_init(&new_thread->_machdep,
+ stack->base, stack->size, _thread_start);
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c
index 56d6c7a3999..716c64f63cb 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.9 1999/11/25 07:01:37 d Exp $ */
+/* $OpenBSD: uthread_kern.c,v 1.10 2000/10/04 05:55:35 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -39,7 +39,6 @@
#include <string.h>
#include <poll.h>
#include <unistd.h>
-#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -77,6 +76,7 @@ void
_thread_kern_sched(struct sigcontext * scp)
{
pthread_t pthread, pthread_h = NULL;
+ pthread_t old_thread_run;
struct itimerval itimer;
struct timespec ts, ts1;
struct timeval tv, tv1;
@@ -100,29 +100,10 @@ _thread_kern_sched(struct sigcontext * scp)
/*
* Save floating point state.
*/
- _thread_machdep_save_float_state(_thread_run);
+ _thread_machdep_save_float_state(&_thread_run->_machdep);
/* Flag the signal context as the last state saved: */
_thread_run->sig_saved = 1;
- }
- /* Save the state of the current thread: */
- else if (_thread_machdep_setjmp(_thread_run->saved_jmp_buf) != 0) {
- /*
- * 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;
-
- if (_sched_switch_hook != NULL) {
- /* Run the installed switch hook: */
- thread_run_switch_hook(_last_user_thread, _thread_run);
- }
-
- _thread_check_cancel();
-
- return;
} else
/* Flag the jump buffer was the last state saved: */
_thread_run->sig_saved = 0;
@@ -134,12 +115,15 @@ _thread_kern_sched(struct sigcontext * scp)
/* Save errno. */
_thread_run->error = errno;
+ /* Save the current thread to switch from */
+ old_thread_run = _thread_run;
+
/*
* 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).
+ * switch.
*/
while (!(TAILQ_EMPTY(&_thread_list))) {
/* Get the current time of day: */
@@ -541,7 +525,7 @@ _thread_kern_sched(struct sigcontext * scp)
/*
* Restore floating point state.
*/
- _thread_machdep_restore_float_state(_thread_run);
+ _thread_machdep_restore_float_state(&_thread_run->_machdep);
/*
* Do a sigreturn to restart the thread that
@@ -561,15 +545,33 @@ _thread_kern_sched(struct sigcontext * scp)
_thread_sys_sigreturn(&_thread_run->saved_sigcontext);
} else {
/*
- * Do a longjmp to restart the thread that
- * was context switched out (by a longjmp to
- * a different thread):
+ * This is the normal way out of the scheduler.
+ */
+ _thread_kern_in_sched = 0;
+
+ if (_sched_switch_hook != NULL) {
+ /* Run the installed switch hook: */
+ thread_run_switch_hook(_last_user_thread,
+ _thread_run);
+ }
+
+ _thread_check_cancel();
+
+ /*
+ * Resume thread _thread_run.
*/
- _thread_machdep_longjmp(_thread_run->saved_jmp_buf, 1);
+ _thread_machdep_switch(&_thread_run->_machdep,
+ &old_thread_run->_machdep);
+ /*
+ * This thread is now the new _thread_run
+ * again.
+ */
+ return;
+
}
/* This point should not be reached. */
- PANIC("Thread has returned from sigreturn or longjmp");
+ PANIC("Thread has returned from sigreturn or switch");
}
}