From: Alastair Bridgewater Date: Fri, 6 Aug 2010 18:47:50 +0000 (+0000) Subject: 1.0.41.11: gc: Interrupt contexts and stacks should be scavenged per-thread. X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=568725aaf7d2d3dae486cd85210eb514c856fdb7;p=sbcl.git 1.0.41.11: gc: Interrupt contexts and stacks should be scavenged per-thread. * 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? --- diff --git a/src/runtime/cheneygc.c b/src/runtime/cheneygc.c index cf79fc3..403c31a 100644 --- a/src/runtime/cheneygc.c +++ b/src/runtime/cheneygc.c @@ -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)); diff --git a/src/runtime/gc-internal.h b/src/runtime/gc-internal.h index 3d43fab..d45764d 100644 --- a/src/runtime/gc-internal.h +++ b/src/runtime/gc-internal.h @@ -17,6 +17,7 @@ #define _GC_INTERNAL_H_ #include +#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); diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index d833733..be171ba 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -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 diff --git a/version.lisp-expr b/version.lisp-expr index 58f93f4..2bca10b 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".) -"1.0.41.10" +"1.0.41.11"