0.8.3.79
authorDaniel Barlow <dan@telent.net>
Thu, 18 Sep 2003 23:15:56 +0000 (23:15 +0000)
committerDaniel Barlow <dan@telent.net>
Thu, 18 Sep 2003 23:15:56 +0000 (23:15 +0000)
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
src/runtime/interrupt.c
src/runtime/thread.c
tests/threads.impure.lisp
version.lisp-expr

index 5ca100a..3a7dccb 100644 (file)
@@ -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&& esp1<th->control_stack_end){
+                   if(esp1<esp) esp=esp1;
+                   for(ptr = (void **)(c+1); ptr>=(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;i<free;i++){
-           os_context_t *c=th->interrupt_contexts[i];
-           if(c>=th->control_stack_end && c<esp) continue;
-           for(ptr = (void **)(c+1); ptr>=(void **)c; ptr--) {
-               preserve_pointer(*ptr);
-           }
-       }
     }
 
 #if QSHOW
index 7b46652..fdbbb9d 100644 (file)
@@ -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);
 }
index 78a3ec3..80be925 100644 (file)
@@ -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);
index 8d00ae7..9e4fc6b 100644 (file)
 
 (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 ()
index 6d2742e..d3c49a8 100644 (file)
@@ -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"