1.0.41.11: gc: Interrupt contexts and stacks should be scavenged per-thread.
[sbcl.git] / src / runtime / cheneygc.c
index 4253892..403c31a 100644 (file)
@@ -61,31 +61,6 @@ tv_diff(struct timeval *x, struct timeval *y)
 }
 #endif
 
-#define BYTES_ZERO_BEFORE_END (1<<12)
-
-/* FIXME do we need this?  Doesn't it duplicate lisp code in
- * scrub-control-stack? */
-
-static void
-zero_stack(void)
-{
-    lispobj *ptr = current_control_stack_pointer;
- search:
-    do {
-        if (*ptr)
-            goto fill;
-        ptr++;
-    } while (((unsigned long)ptr) & (BYTES_ZERO_BEFORE_END-1));
-    return;
- fill:
-    do {
-        *ptr++ = 0;
-    } while (((unsigned long)ptr) & (BYTES_ZERO_BEFORE_END-1));
-
-    goto search;
-}
-
-
 void *
 gc_general_alloc(long bytes, int page_type_flag, int quick_p) {
     lispobj *new=new_space_free_pointer;
@@ -132,9 +107,7 @@ collect_garbage(generation_index_t ignore)
 
     /* it's possible that signals are blocked already if this was called
      * from a signal handler (e.g. with the sigsegv gc_trigger stuff) */
-    sigemptyset(&tmp);
-    sigaddset_blockable(&tmp);
-    thread_sigmask(SIG_BLOCK, &tmp, &old);
+    block_blockable_signals(0, &old);
 
     current_static_space_free_pointer =
         (lispobj *) ((unsigned long)
@@ -167,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",
@@ -260,7 +233,7 @@ collect_garbage(generation_index_t ignore)
 #ifdef PRINTNOISE
     printf("Zeroing empty part of control stack ...\n");
 #endif
-    zero_stack();
+    scrub_control_stack();
     set_auto_gc_trigger(size_retained+bytes_consed_between_gcs);
     thread_sigmask(SIG_SETMASK, &old, 0);
 
@@ -418,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));
 
 
@@ -597,7 +568,7 @@ void set_auto_gc_trigger(os_vm_size_t dynamic_usage)
         lose("set_auto_gc_trigger: tried to set gc trigger too high! (0x%08lx)\n",
              (unsigned long)dynamic_usage);
 
-#if defined(SUNOS) || defined(SOLARIS)
+#if defined(SUNOS) || defined(SOLARIS) || defined(LISP_FEATURE_HPUX)
     os_invalidate(addr, length);
 #else
     os_protect(addr, length, 0);
@@ -617,7 +588,7 @@ void clear_auto_gc_trigger(void)
     addr = (os_vm_address_t)current_auto_gc_trigger;
     length = dynamic_space_size + (os_vm_address_t)current_dynamic_space - addr;
 
-#if defined(SUNOS) || defined(SOLARIS)
+#if defined(SUNOS) || defined(SOLARIS) || defined(LISP_FEATURE_HPUX)
     /* don't want to force whole space into swapping mode... */
     os_validate(addr, length);
 #else
@@ -654,6 +625,8 @@ cheneygc_handle_wp_violation(os_context_t *context, void *addr)
                      * the PA section */
                     SetSymbolValue(GC_PENDING,T,thread);
                     arch_set_pseudo_atomic_interrupted(context);
+                    maybe_save_gc_mask_and_block_deferrables
+                        (os_context_sigmask_addr(context));
                 } else {
                     maybe_gc(context);
                 }