1.0.41.11: gc: Interrupt contexts and stacks should be scavenged per-thread.
authorAlastair Bridgewater <lisphacker@users.sourceforge.net>
Fri, 6 Aug 2010 18:47:50 +0000 (18:47 +0000)
committerAlastair Bridgewater <lisphacker@users.sourceforge.net>
Fri, 6 Aug 2010 18:47:50 +0000 (18:47 +0000)
  * Pass an explicit thread argument to scavenge_interrupt_contexts()
instead of having it call arch_os_get_current_thread(), saving the
extra call on cheneygc and allowing multiple threads on gencgc.

  * On gencgc, the same applies to scavenge_control_stack().

  * On gencgc, don't scrub the control stack when scavenging, wait
until after the scavenging is done (it's done by the stop-for-gc
handler on other threads).

  * On gencgc, scavenge interrupt contexts and control stacks for
all threads, not just the current thread.

  * On a minor note, the code for scavenging interrupt contexts is
largely unchanged between cheneygc and gencgc.  Perhaps it should
be re-unified in gc-common.c?

src/runtime/cheneygc.c
src/runtime/gc-internal.h
src/runtime/gencgc.c
version.lisp-expr

index cf79fc3..403c31a 100644 (file)
@@ -140,7 +140,7 @@ collect_garbage(generation_index_t ignore)
 #ifdef PRINTNOISE
     printf("Scavenging interrupt contexts ...\n");
 #endif
-    scavenge_interrupt_contexts();
+    scavenge_interrupt_contexts(th);
 
 #ifdef PRINTNOISE
     printf("Scavenging interrupt handlers (%d bytes) ...\n",
@@ -391,13 +391,11 @@ scavenge_interrupt_context(os_context_t *context)
 #endif
 }
 
-void scavenge_interrupt_contexts(void)
+void scavenge_interrupt_contexts(struct thread *th)
 {
     int i, index;
     os_context_t *context;
 
-    struct thread *th=arch_os_get_current_thread();
-
     index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,0));
 
 
index 3d43fab..d45764d 100644 (file)
@@ -17,6 +17,7 @@
 #define _GC_INTERNAL_H_
 
 #include <genesis/simple-fun.h>
+#include "thread.h"
 
 /* disabling gc assertions made no discernable difference to GC speed,
  * last I tried it - dan 2003.12.21
@@ -112,7 +113,7 @@ extern struct weak_pointer *weak_pointers; /* in gc-common.c */
 extern struct hash_table *weak_hash_tables; /* in gc-common.c */
 
 extern void scavenge(lispobj *start, long n_words);
-extern void scavenge_interrupt_contexts(void);
+extern void scavenge_interrupt_contexts(struct thread *thread);
 extern void scav_weak_hash_tables(void);
 extern void scan_weak_hash_tables(void);
 extern void scan_weak_pointers(void);
index d833733..be171ba 100644 (file)
@@ -3824,22 +3824,17 @@ write_protect_generation_pages(generation_index_t generation)
 #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
 
 static void
-scavenge_control_stack()
+scavenge_control_stack(struct thread *th)
 {
     unsigned long control_stack_size;
 
     /* This is going to be a big problem when we try to port threads
      * to PPC... CLH */
-    struct thread *th = arch_os_get_current_thread();
     lispobj *control_stack =
         (lispobj *)(th->control_stack_start);
 
     control_stack_size = current_control_stack_pointer - control_stack;
     scavenge(control_stack, control_stack_size);
-
-    /* Scrub the unscavenged control stack space, so that we can't run
-     * into any stale pointers in a later GC. */
-    scrub_control_stack();
 }
 
 /* Scavenging Interrupt Contexts */
@@ -3963,14 +3958,12 @@ scavenge_interrupt_context(os_context_t * context)
 }
 
 void
-scavenge_interrupt_contexts(void)
+scavenge_interrupt_contexts(struct thread *th)
 {
     int i, index;
     os_context_t *context;
 
-    struct thread *th=arch_os_get_current_thread();
-
-    index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,0));
+    index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th));
 
 #if defined(DEBUG_PRINT_CONTEXT_INDEX)
     printf("Number of active contexts: %d\n", index);
@@ -4156,8 +4149,18 @@ garbage_collect_generation(generation_index_t generation, int raise)
      * If not x86, we need to scavenge the interrupt context(s) and the
      * control stack.
      */
-    scavenge_interrupt_contexts();
-    scavenge_control_stack();
+    {
+        struct thread *th;
+        for_each_thread(th) {
+            scavenge_interrupt_contexts(th);
+            scavenge_control_stack(th);
+        }
+
+        /* Scrub the unscavenged control stack space, so that we can't run
+         * into any stale pointers in a later GC (this is done by the
+         * stop-for-gc handler in the other threads). */
+        scrub_control_stack();
+    }
 #endif
 
     /* Scavenge the Lisp functions of the interrupt handlers, taking
index 58f93f4..2bca10b 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".)
-"1.0.41.10"
+"1.0.41.11"