From: Thiemo S. <th...@ne...> - 2005-05-30 16:42:14
|
Thiemo Seufer wrote: > Hello All, > > this is an attempt to get the os_context_t / void_context handling > right. It should only change the behaviour on sparc: ST_FLUSH_WINDOWS > is now always done before a context is used, and for sparc-linux the > context is converted back for signal handler calls. sparc-linux also > missed a pointer dereference in arch_os_get_context. > > The ST_FLUSH_WINDOWS in arch_os_get_void_context is probably not > needed because it was already done in arch_os_get_context, I don't > know enough about sparc to be sure and chose the safer version. > > This patch is _not_ tested for sparc, only for mips. Updated to account for sparc linux weirdness, with the second ST_FLUSH_WINDOWS removed again. Thiemo Index: src/runtime/alpha-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/alpha-linux-os.h,v retrieving revision 1.4 diff -u -p -r1.4 alpha-linux-os.h --- src/runtime/alpha-linux-os.h 1 Sep 2002 22:34:18 -0000 1.4 +++ src/runtime/alpha-linux-os.h 30 May 2005 16:18:49 -0000 @@ -8,6 +8,10 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + unsigned long os_context_fp_control(os_context_t *context); #endif /* _ALPHA_LINUX_OS_H */ Index: src/runtime/alpha-osf1-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/alpha-osf1-os.h,v retrieving revision 1.2 diff -u -p -r1.2 alpha-osf1-os.h --- src/runtime/alpha-osf1-os.h 18 Jul 2002 17:47:34 -0000 1.2 +++ src/runtime/alpha-osf1-os.h 30 May 2005 16:18:49 -0000 @@ -7,4 +7,8 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + #endif /* _ALPHA_OSF1_OS_H */ Index: src/runtime/hppa-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/hppa-linux-os.h,v retrieving revision 1.2 diff -u -p -r1.2 hppa-linux-os.h --- src/runtime/hppa-linux-os.h 1 Sep 2002 22:34:18 -0000 1.2 +++ src/runtime/hppa-linux-os.h 30 May 2005 16:18:50 -0000 @@ -10,6 +10,10 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + unsigned long os_context_fp_control(os_context_t *context); void os_restore_fp_control(os_context_t *context); Index: src/runtime/interrupt.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.c,v retrieving revision 1.74 diff -u -p -r1.74 interrupt.c --- src/runtime/interrupt.c 29 May 2005 21:08:46 -0000 1.74 +++ src/runtime/interrupt.c 30 May 2005 16:18:50 -0000 @@ -66,7 +66,6 @@ -void run_deferred_handler(struct interrupt_data *data, void *v_context) ; static void store_signal_data_for_later (struct interrupt_data *data, void *handler, int signal, siginfo_t *info, @@ -86,6 +85,12 @@ extern volatile lispobj all_threads_lock #define REAL_SIGSET_SIZE_BYTES ((NSIG/8)) +static inline void +sigcopyset(sigset_t *new, sigset_t *old) +{ + memcpy(new, old, REAL_SIGSET_SIZE_BYTES); +} + void sigaddset_blockable(sigset_t *s) { sigaddset(s, SIGHUP); @@ -315,14 +320,13 @@ interrupt_handle_pending(os_context_t *c * os_context for the signal we're currently in the handler for. * This should ensure that when we return from the handler the * blocked signals are unblocked */ - - memcpy(os_context_sigmask_addr(context), &data->pending_mask, - REAL_SIGSET_SIZE_BYTES); - + sigcopyset(os_context_sigmask_addr(context), &data->pending_mask); sigemptyset(&data->pending_mask); - /* This will break on sparc linux: the deferred handler really wants - * to be called with a void_context */ - run_deferred_handler(data,(void *)context); + + (*(data->pending_handler)) + (data->pending_signal,&(data->pending_info), + *arch_os_get_void_context(&context)); + data->pending_handler = NULL; } /* @@ -341,9 +345,8 @@ interrupt_handle_pending(os_context_t *c */ void -interrupt_handle_now(int signal, siginfo_t *info, void *void_context) +interrupt_handle_now(int signal, siginfo_t *info, os_context_t *context) { - os_context_t *context = (os_context_t*)void_context; struct thread *thread=arch_os_get_current_thread(); #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) boolean were_in_lisp; @@ -417,8 +420,8 @@ interrupt_handle_now(int signal, siginfo /* Allow signals again. */ sigprocmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); - - (*handler.c)(signal, info, void_context); + + (*handler.c)(signal, info, *arch_os_get_void_context(&context)); } #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) @@ -441,13 +444,6 @@ interrupt_handle_now(int signal, siginfo * already; we're just doing the Lisp-level processing now that we * put off then */ -void -run_deferred_handler(struct interrupt_data *data, void *v_context) { - (*(data->pending_handler)) - (data->pending_signal,&(data->pending_info), v_context); - data->pending_handler=0; -} - boolean maybe_defer_handler(void *handler, struct interrupt_data *data, int signal, siginfo_t *info, os_context_t *context) @@ -472,6 +468,7 @@ maybe_defer_handler(void *handler, struc } return 0; } + static void store_signal_data_for_later (struct interrupt_data *data, void *handler, int signal, @@ -484,13 +481,10 @@ store_signal_data_for_later (struct inte if(context) { /* the signal mask in the context (from before we were * interrupted) is copied to be restored when - * run_deferred_handler happens. Then the usually-blocked + * interrupt_handle_pending happens. Then the usually-blocked * signals are added to the mask in the context so that we are * running with blocked signals when the handler returns */ - sigemptyset(&(data->pending_mask)); - memcpy(&(data->pending_mask), - os_context_sigmask_addr(context), - REAL_SIGSET_SIZE_BYTES); + sigcopyset(&(data->pending_mask), os_context_sigmask_addr(context)); sigaddset_blockable(os_context_sigmask_addr(context)); } else { /* this is also called from gencgc alloc(), in which case @@ -539,8 +533,8 @@ sig_stop_for_gc_handler(int signal, sigi /* need the context stored so it can have registers scavenged */ fake_foreign_function_call(context); - sigemptyset(&ss); - for(i=1;i<NSIG;i++) sigaddset(&ss,i); /* Block everything. */ + /* Block everything. */ + sigfillset(&ss); sigprocmask(SIG_BLOCK,&ss,0); /* The GC can't tell if a thread is a zombie, so this would be a @@ -554,7 +548,8 @@ sig_stop_for_gc_handler(int signal, sigi } thread->state=STATE_STOPPED; - sigemptyset(&ss); sigaddset(&ss,SIG_STOP_FOR_GC); + sigemptyset(&ss); + sigaddset(&ss,SIG_STOP_FOR_GC); sigwaitinfo(&ss,0); if(thread->state!=STATE_STOPPED) { lose("sig_stop_for_gc_handler: wrong thread state on wakeup: %ld\n", @@ -726,7 +721,7 @@ void arrange_return_to_lisp_function(os_ #ifdef LISP_FEATURE_SB_THREAD void interrupt_thread_handler(int num, siginfo_t *info, void *v_context) { - os_context_t *context = (os_context_t*)arch_os_get_context(&v_context); + os_context_t *context = arch_os_get_context(&v_context); struct thread *th=arch_os_get_current_thread(); struct interrupt_data *data= th ? th->interrupt_data : global_interrupt_data; @@ -736,7 +731,7 @@ void interrupt_thread_handler(int num, s arrange_return_to_lisp_function(context,info->si_value.sival_int); } -void thread_exit_handler(int num, siginfo_t *info, void *v_context) +void thread_exit_handler(int num, siginfo_t *info, void *void_context) { /* called when a child thread exits */ mark_dead_threads(); } @@ -800,7 +795,8 @@ extern unsigned long bytes_consed_betwee boolean interrupt_maybe_gc(int signal, siginfo_t *info, void *void_context) { - os_context_t *context=(os_context_t *) void_context; + os_context_t *context = arch_os_get_context(&void_context); + struct thread *th=arch_os_get_current_thread(); struct interrupt_data *data= th ? th->interrupt_data : global_interrupt_data; @@ -869,7 +865,8 @@ boolean interrupt_maybe_gc_int(int signal, siginfo_t *info, void *void_context) { sigset_t new; - os_context_t *context=(os_context_t *) void_context; + os_context_t *context = arch_os_get_context(&void_context); + fake_foreign_function_call(context); /* SUB-GC may return without GCing if *GC-INHIBIT* is set, in @@ -980,7 +977,7 @@ install_handler(int signal, void handler } void -interrupt_init() +interrupt_init(void) { int i; SHOW("entering interrupt_init()"); Index: src/runtime/interrupt.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.h,v retrieving revision 1.14 diff -u -p -r1.14 interrupt.h --- src/runtime/interrupt.h 14 Mar 2005 09:54:49 -0000 1.14 +++ src/runtime/interrupt.h 30 May 2005 16:18:50 -0000 @@ -45,7 +45,7 @@ extern void interrupt_init(); extern void fake_foreign_function_call(os_context_t* context); extern void undo_fake_foreign_function_call(os_context_t* context); extern void arrange_return_to_lisp_function(os_context_t *, lispobj); -extern void interrupt_handle_now(int, siginfo_t*, void*); +extern void interrupt_handle_now(int, siginfo_t*, os_context_t*); extern void interrupt_handle_pending(os_context_t*); extern void interrupt_internal_error(int, siginfo_t*, os_context_t*, boolean continuable); @@ -64,8 +64,6 @@ extern void undoably_install_low_level_i extern unsigned long install_handler(int signal, void handler(int, siginfo_t*, void*)); -extern union interrupt_handler interrupt_handlers[NSIG]; - /* Set all blockable signals into *s. */ void sigaddset_blockable(sigset_t *s); Index: src/runtime/mips-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/mips-linux-os.h,v retrieving revision 1.2 diff -u -p -r1.2 mips-linux-os.h --- src/runtime/mips-linux-os.h 30 Apr 2005 09:40:41 -0000 1.2 +++ src/runtime/mips-linux-os.h 30 May 2005 16:18:50 -0000 @@ -8,6 +8,10 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + unsigned int os_context_fp_control(os_context_t *context); void os_restore_fp_control(os_context_t *context); unsigned int os_context_bd_cause(os_context_t *context); Index: src/runtime/ppc-darwin-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/ppc-darwin-os.h,v retrieving revision 1.2 diff -u -p -r1.2 ppc-darwin-os.h --- src/runtime/ppc-darwin-os.h 17 Apr 2005 19:41:28 -0000 1.2 +++ src/runtime/ppc-darwin-os.h 30 May 2005 16:18:50 -0000 @@ -5,5 +5,9 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + #define DARWIN_FIX_CONTEXT(c) (c->uc_mcontext->ss.xer)^=0x80; #endif /* _PPC_DARWIN_OS_H */ Index: src/runtime/ppc-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/ppc-linux-os.h,v retrieving revision 1.5 diff -u -p -r1.5 ppc-linux-os.h --- src/runtime/ppc-linux-os.h 3 Apr 2003 18:27:27 -0000 1.5 +++ src/runtime/ppc-linux-os.h 30 May 2005 16:18:50 -0000 @@ -8,6 +8,10 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + unsigned long os_context_fp_control(os_context_t *context); void os_restore_fp_control(os_context_t *context); extern struct thread *arch_os_get_current_thread(); Index: src/runtime/sparc-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/sparc-linux-os.h,v retrieving revision 1.4 diff -u -p -r1.4 sparc-linux-os.h --- src/runtime/sparc-linux-os.h 1 Sep 2002 22:34:18 -0000 1.4 +++ src/runtime/sparc-linux-os.h 30 May 2005 16:18:50 -0000 @@ -6,7 +6,12 @@ typedef unsigned long os_context_registe static inline os_context_t *arch_os_get_context(void **void_context) { asm volatile ("ta 0x03"); /* ta ST_FLUSH_WINDOWS */ - return (os_context_t *) (void_context + 37); + return (os_context_t *)(void_context + 37); +} + +static inline void **arch_os_get_void_context(os_context_t **context) { + /* ST_FLUSH_WINDOWS already done in arch_os_get_context */ + return ((void **)context) - 37; } unsigned long os_context_fp_control(os_context_t *context); Index: src/runtime/sparc-sunos-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/sparc-sunos-os.h,v retrieving revision 1.2 diff -u -p -r1.2 sparc-sunos-os.h --- src/runtime/sparc-sunos-os.h 18 Jul 2002 17:47:34 -0000 1.2 +++ src/runtime/sparc-sunos-os.h 30 May 2005 16:18:50 -0000 @@ -8,4 +8,9 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) (*void_context); } +static inline void **arch_os_get_void_context(os_context_t **context) { + /* ST_FLUSH_WINDOWS already done in arch_os_get_context */ + return (void **)context; +} + #endif /* _SPARC_SOLARIS_OS_H */ Index: src/runtime/x86-64-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-64-linux-os.h,v retrieving revision 1.3 diff -u -p -r1.3 x86-64-linux-os.h --- src/runtime/x86-64-linux-os.h 14 Apr 2005 22:34:45 -0000 1.3 +++ src/runtime/x86-64-linux-os.h 30 May 2005 16:18:50 -0000 @@ -8,6 +8,10 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + unsigned long os_context_fp_control(os_context_t *context); void os_restore_fp_control(os_context_t *context); Index: src/runtime/x86-linux-os.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-linux-os.h,v retrieving revision 1.6 diff -u -p -r1.6 x86-linux-os.h --- src/runtime/x86-linux-os.h 5 Apr 2003 13:04:15 -0000 1.6 +++ src/runtime/x86-linux-os.h 30 May 2005 16:18:50 -0000 @@ -8,6 +8,10 @@ static inline os_context_t *arch_os_get_ return (os_context_t *) *void_context; } +static inline void **arch_os_get_void_context(os_context_t **context) { + return (void **)context; +} + unsigned long os_context_fp_control(os_context_t *context); void os_restore_fp_control(os_context_t *context); |