diff options
author | David Leonard <d@cvs.openbsd.org> | 2000-10-04 05:55:36 +0000 |
---|---|---|
committer | David Leonard <d@cvs.openbsd.org> | 2000-10-04 05:55:36 +0000 |
commit | 8e95e2f842b2fdd99c416cc00a8d321656fea5af (patch) | |
tree | ae270251a663e179dd260f976e6b3ecb477678cf /lib/libc_r/uthread | |
parent | 367c0082943cc6fa224d021a045222f13f86cfe4 (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.h | 24 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_create.c | 15 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_kern.c | 60 |
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"); } } |