From 1b56edad1bf47547bbcd3b98c809b6f933ba937e Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Thu, 18 Sep 2003 23:15:56 +0000 Subject: [PATCH] 0.8.3.79 GC fix fixes Rearrange the sigcontext GCing a bit and add commentary describing what's going on Delete debugging message accidentally committed in .76 tests/threads.impure.lisp now works (but don't worry, I have another test locally which still kills sbcl sometimes) --- src/runtime/gencgc.c | 40 +++++++++++++++++++++++++++------------- src/runtime/interrupt.c | 4 +--- src/runtime/thread.c | 2 +- tests/threads.impure.lisp | 5 +++-- version.lisp-expr | 2 +- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 5ca100a..3a7dccb 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -3671,29 +3671,43 @@ garbage_collect_generation(int generation, int raise) unprotect_oldspace(); /* Scavenge the stacks' conservative roots. */ + + /* there are potentially two stacks for each thread: the main + * stack, which may contain Lisp pointers, and the alternate stack. + * We don't ever run Lisp code on the altstack, but it may + * host a sigcontext with lisp objects in it */ + + /* what we need to do: (1) find the stack pointer for the main + * stack; scavenge it (2) find the interrupt context on the + * alternate stack that might contain lisp values, and scavenge + * that */ + + /* we assume that none of the preceding applies to the thread that + * initiates GC. If you ever call GC from inside an altstack + * handler, you will lose. */ for_each_thread(th) { void **ptr; void **esp= (void **) &raise; - int i=0,free; + int i,free; #ifdef LISP_FEATURE_SB_THREAD if(th!=arch_os_get_current_thread()) { - os_context_t *last_context=get_interrupt_context_for_thread(th); - esp = (void **)*os_context_register_addr(last_context,reg_ESP); + void **esp1; + free=fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th)); + for(i=free-1;i>=0;i--) { + os_context_t *c=th->interrupt_contexts[i]; + esp1 = (void **) *os_context_register_addr(c,reg_ESP); + if(esp1>=th->control_stack_start&& esp1control_stack_end){ + if(esp1=(void **)c; ptr--) { + preserve_pointer(*ptr); + } + } + } } #endif for (ptr = (void **)th->control_stack_end; ptr > esp; ptr--) { preserve_pointer(*ptr); } - /* also need to check registers in any interrupt contexts on - * an alternate signal stack */ - free=fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th)); - for(i=0;iinterrupt_contexts[i]; - if(c>=th->control_stack_end && c=(void **)c; ptr--) { - preserve_pointer(*ptr); - } - } } #if QSHOW diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 7b46652..fdbbb9d 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -70,7 +70,7 @@ static void store_signal_data_for_later (struct interrupt_data *data, boolean interrupt_maybe_gc_int(int signal, siginfo_t *info, void *v_context); extern lispobj all_threads_lock; -extern int countdown_to_gc; +extern volatile int countdown_to_gc; /* * This is a workaround for some slightly silly Linux/GNU Libc @@ -425,8 +425,6 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) void run_deferred_handler(struct interrupt_data *data, void *v_context) { - fprintf(stderr,"Running deferred handler for %d, 0x%x\n", - data->pending_signal, data->pending_handler); (*(data->pending_handler)) (data->pending_signal,&(data->pending_info), v_context); } diff --git a/src/runtime/thread.c b/src/runtime/thread.c index 78a3ec3..80be925 100644 --- a/src/runtime/thread.c +++ b/src/runtime/thread.c @@ -24,7 +24,7 @@ int dynamic_values_bytes=4096*sizeof(lispobj); /* same for all threads */ struct thread *all_threads; lispobj all_threads_lock; -int countdown_to_gc; +volatile int countdown_to_gc; extern struct interrupt_data * global_interrupt_data; void get_spinlock(lispobj *word,int value); diff --git a/tests/threads.impure.lisp b/tests/threads.impure.lisp index 8d00ae7..9e4fc6b 100644 --- a/tests/threads.impure.lisp +++ b/tests/threads.impure.lisp @@ -131,8 +131,9 @@ (defun alloc-stuff () (copy-list '(1 2 3 4 5))) (let ((c (test-interrupt (lambda () (loop (alloc-stuff)))))) - ;; NB this only works on x86 - (loop + ;; NB this only works on x86: other ports don't have a symbol for + ;; pseudo-atomic atomicity + (dotimes (i 100) (sleep (random 1d0)) (interrupt-thread c (lambda () diff --git a/version.lisp-expr b/version.lisp-expr index 6d2742e..d3c49a8 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.8.3.78" +"0.8.3.79" -- 1.7.10.4