logo       
Google Custom Search
    AddThis Social Bookmark Button

CVS: sbcl/src/runtime interrupt.c,1.32.4.3,1.32.4.4 thread.c,1.1.2.8,1.1.2.: msg#00086

Subject: CVS: sbcl/src/runtime interrupt.c,1.32.4.3,1.32.4.4 thread.c,1.1.2.8,1.1.2.9 thread.h,1.1.2.7,1.1.2.8 validate.c,1.13.4.1,1.13.4.2 validate.h,1.7.4.1,1.7.4.2 x86-linux-os.c,1.7.4.4,1.7.4.5
Update of /cvsroot/sbcl/sbcl/src/runtime
In directory sc8-pr-cvs1:/tmp/cvs-serv12069/src/runtime

Modified Files:
      Tag: dan_native_threads_branch
        interrupt.c thread.c thread.h validate.c validate.h 
        x86-linux-os.c 
Log Message:
0.7.54.thread.13
        #+quis-custodiet-control-stack

        Reintroduce the control stack exhaustion checking that had
        been disabled when doing the original cope-with-multi-threads
        work.

        New static symbol *current-thread* (actually an aligned
        machine word that looks like a fixnum, *current-thread-address*
        would be a better name)

        protect_control_stack_guard_page gets another arg for the
        thread whose control stack needs guarding.  Lisp glue hides
        this, though
        
        Nopify uninstall_low_level_interrupt_handlers_atexit for the
        time being: we don't want the first exiting thread to remove
        our handlers for all the others



Index: interrupt.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.c,v
retrieving revision 1.32.4.3
retrieving revision 1.32.4.4
diff -u -d -r1.32.4.3 -r1.32.4.4
--- interrupt.c 2 Dec 2002 15:57:53 -0000       1.32.4.3
+++ interrupt.c 18 Dec 2002 17:23:44 -0000      1.32.4.4
@@ -107,7 +107,7 @@
  */
 
 void 
-build_fake_control_stack_frames(os_context_t *context)
+build_fake_control_stack_frames(struct thread *th,os_context_t *context)
 {
 #ifndef LISP_FEATURE_X86
     
@@ -177,7 +177,7 @@
        (lispobj *)(*os_context_register_addr(context, reg_BSP));
 #endif
 
-    build_fake_control_stack_frames(context);
+    build_fake_control_stack_frames(thread,context);
 
     /* Do dynamic binding of the active interrupt context index
      * and save the context in the context array. */
@@ -524,9 +524,57 @@
 
 boolean handle_control_stack_guard_triggered(os_context_t *context,void *addr)
 {
-    /* not thinking too hard about this just now */
-    /* FIXME so think! */
-    return 0;
+    struct thread *th=arch_os_get_current_thread();
+    /* note the os_context hackery here.  When the signal handler returns, 
+     * it won't go back to what it was doing ... */
+    if(addr>=(void *)CONTROL_STACK_GUARD_PAGE(th) && 
+       addr<(void *)(CONTROL_STACK_GUARD_PAGE(th)+os_vm_page_size)) {
+       void *fun;
+       void *code;
+       /* fprintf(stderr, "hit end of control stack\n");  */
+       /* we hit the end of the control stack.  disable protection
+        * temporarily so the error handler has some headroom */
+       protect_control_stack_guard_page(th,0L);
+
+       fun = (void *)
+           native_pointer((lispobj) 
SymbolFunction(CONTROL_STACK_EXHAUSTED_ERROR));
+       code = &(((struct simple_fun *) fun)->code);
+
+       /* Build a stack frame showing `interrupted' so that the
+        * user's backtrace makes (as much) sense (as usual) */
+       build_fake_control_stack_frames(th,context);
+       /* signal handler will "return" to this error-causing function */
+       *os_context_pc_addr(context) = code;
+#ifdef LISP_FEATURE_X86
+       *os_context_register_addr(context,reg_ECX) = 0; 
+#else
+       /* this much of the calling convention is common to all
+          non-x86 ports */
+       *os_context_register_addr(context,reg_NARGS) = 0; 
+       *os_context_register_addr(context,reg_LIP) = code;
+       *os_context_register_addr(context,reg_CFP) = 
+           current_control_frame_pointer;
+#endif
+#ifdef ARCH_HAS_NPC_REGISTER
+       *os_context_npc_addr(context) =
+           4 + *os_context_pc_addr(context);
+#endif
+#ifdef LISP_FEATURE_SPARC
+       /* Bletch.  This is a feature of the SPARC calling convention,
+          which sadly I'm not going to go into in large detail here,
+          as I don't know it well enough.  Suffice to say that if the
+          line 
+
+          (INST MOVE CODE-TN FUNCTION) 
+
+          in compiler/sparc/call.lisp is changed, then this bit can
+          probably go away.  -- CSR, 2002-07-24 */
+       *os_context_register_addr(context,reg_CODE) = 
+           fun + FUN_POINTER_LOWTAG;
+#endif
+       return 1;
+    }
+    else return 0;
 }
 
 #ifndef LISP_FEATURE_X86
@@ -605,6 +653,7 @@
 uninstall_low_level_interrupt_handlers_atexit(void)
 {
     int signal;
+#if 0
     for (signal = 0; signal < NSIG; ++signal) {
        struct low_level_signal_handler_state
            *old_low_level_signal_handler_state =
@@ -617,8 +666,14 @@
            sigaction(signal, &sa, NULL);
        }
     }
+#endif
 }
 
+/* FIXME the "undoable" below is currently a lie.  We don't want to 
+ * remove any signal handlers while there are still >0 threads left, 
+ * so that atexit thing has been disabled for the moment
+ */
+
 /* Undoably install a special low-level handler for signal; or if
  * handler is SIG_DFL, remove any special handling for signal.
  *
@@ -651,12 +706,9 @@
     sigaddset_blockable(&sa.sa_mask);
     sa.sa_flags = SA_SIGINFO | SA_RESTART;
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
-    /* Signal handlers are run on the control stack, so if it is exhausted
-     * we had better use an alternate stack for whatever signal tells us
-     * we've exhausted it */
-    /* XXX this bit got untimely ripped out in pursuit of threads */
+    if(signal==SIG_MEMORY_FAULT) sa.sa_flags|= SA_ONSTACK;
 #endif
-    
+
     /* In the case of interrupt handlers which are modified more than
      * once, we only save the original unmodified copy. */
     if (!old_low_level_signal_handler_state->was_modified) {
@@ -704,7 +756,6 @@
        sigemptyset(&sa.sa_mask);
        sigaddset_blockable(&sa.sa_mask);
        sa.sa_flags = SA_SIGINFO | SA_RESTART;
-
        sigaction(signal, &sa, NULL);
     }
 

Index: thread.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/Attic/thread.c,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -u -d -r1.1.2.8 -r1.1.2.9
--- thread.c    13 Dec 2002 02:03:27 -0000      1.1.2.8
+++ thread.c    18 Dec 2002 17:23:45 -0000      1.1.2.9
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sched.h>
+#include <stddef.h>
 #ifndef CLONE_PARENT           /* lameass glibc 2.2  doesn't define this */
 #define CLONE_PARENT 0x00008000        /* even though the manpage documents it 
*/
 #endif
@@ -63,11 +64,18 @@
      * having to decide what to do if only some of the allocations
      * succeed */
     spaces=os_validate(0,
-                      THREAD_CONTROL_STACK_SIZE+BINDING_STACK_SIZE+
-                      ALIEN_STACK_SIZE+dynamic_values_bytes);
+                      THREAD_CONTROL_STACK_SIZE+
+                      BINDING_STACK_SIZE+
+                      ALIEN_STACK_SIZE+
+                      dynamic_values_bytes+
+                      32*SIGSTKSZ
+                      );
     if(!spaces) goto cleanup;
     per_thread=(union per_thread_data *)
-       (spaces+THREAD_CONTROL_STACK_SIZE+BINDING_STACK_SIZE+ALIEN_STACK_SIZE);
+       (spaces+
+        THREAD_CONTROL_STACK_SIZE+
+        BINDING_STACK_SIZE+
+        ALIEN_STACK_SIZE);
 
     th=&per_thread->thread;
     if(all_threads) {
@@ -87,8 +95,10 @@
            ->tls_index=make_fixnum(2);
        ((struct symbol *)(CONTROL_STACK_START-OTHER_POINTER_LOWTAG))
            ->tls_index=make_fixnum(3);
-       ((struct symbol *)(ALIEN_STACK-OTHER_POINTER_LOWTAG))
-           ->tls_index=make_fixnum(5);
+       ((struct symbol *)(ALIEN_STACK-OTHER_POINTER_LOWTAG))->tls_index=
+           make_fixnum(THREAD_SLOT_OFFSET_WORDS(alien_stack_pointer));
+       ((struct symbol *)(CURRENT_THREAD-OTHER_POINTER_LOWTAG))
+           ->tls_index=make_fixnum(THREAD_SLOT_OFFSET_WORDS(this));
     }
 
     th->control_stack_start = spaces;
@@ -97,8 +107,13 @@
     th->alien_stack_start=
        (lispobj*)((void*)th->binding_stack_start+BINDING_STACK_SIZE);
     th->binding_stack_pointer=th->binding_stack_start;
+    th->this=th;
+#ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD
     th->alien_stack_pointer=((void *)th->alien_stack_start
                             + ALIEN_STACK_SIZE-4); /* naked 4.  FIXME */
+#else
+    th->alien_stack_pointer=((void *)th->alien_stack_start);
+#endif
     gc_set_region_empty(&th->alloc_region);
     
     bind_variable(CURRENT_CATCH_BLOCK,make_fixnum(0),th);
@@ -108,17 +123,19 @@
     bind_variable(FREE_INTERRUPT_CONTEXT_INDEX,make_fixnum(0),th);
     bind_variable(INTERRUPT_PENDING, NIL,th);
     bind_variable(INTERRUPTS_ENABLED,T,th);
-
     th->next=all_threads;
+    protect_control_stack_guard_page(th,1);
 #if defined(LISP_FEATURE_X86) && defined (LISP_FEATURE_LINUX)
 
     th->unbound_marker=initial_function;
     th->pid=
-       clone(new_thread_trampoline,th->binding_stack_start-2,
+       clone(new_thread_trampoline,
+             (((void*)th->control_stack_start)+THREAD_CONTROL_STACK_SIZE-4),
              (((getpid()!=parent_pid)?CLONE_PARENT:0)
               |CLONE_SIGHAND|CLONE_VM),th);
     fprintf(stderr,"child pid is %d\n",th->pid);
     if(th->pid<=0) goto cleanup;
+
 #else
 #error this stuff presently only works on x86 Linux
 #endif

Index: thread.h
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/Attic/thread.h,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -u -d -r1.1.2.7 -r1.1.2.8
--- thread.h    13 Dec 2002 02:03:27 -0000      1.1.2.7
+++ thread.h    18 Dec 2002 17:23:45 -0000      1.1.2.8
@@ -1,3 +1,7 @@
+
+#if !defined(_INCLUDE_THREAD_H_)
+#define _INCLUDE_THREAD_H_
+
 #include <sys/types.h>
 #include <unistd.h>
 #include "runtime.h"
@@ -10,6 +14,9 @@
 #error "threading doesn't work with cheney gc yet"
 #endif
 
+#define THREAD_SLOT_OFFSET_WORDS(c) \
+ (offsetof(struct thread,c)/(sizeof (struct thread *)))
+
 struct thread {
     lispobj unbound_marker;    /* tls[0] = UNBOUND_MARKER_WIDETAG */
     /* unbound_marker is borrowed very briefly at thread startup to 
@@ -76,3 +83,6 @@
        =val;
 }
 
+    
+
+#endif /* _INCLUDE_THREAD_H_ */

Index: validate.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/validate.c,v
retrieving revision 1.13.4.1
retrieving revision 1.13.4.2
diff -u -d -r1.13.4.1 -r1.13.4.2
--- validate.c  24 Nov 2002 13:14:17 -0000      1.13.4.1
+++ validate.c  18 Dec 2002 17:23:45 -0000      1.13.4.2
@@ -83,14 +83,17 @@
 #ifdef PRINTNOISE
     printf(" done.\n");
 #endif
-    protect_control_stack_guard_page(1); 
 }
 
-void protect_control_stack_guard_page(int protect_p) {
-    /*
-    os_protect(CONTROL_STACK_GUARD_PAGE,
+void protect_control_stack_guard_page(struct thread *th,int protect_p) {
+    fprintf(stderr, "%sprotecting control stack guard page, th=%x, args 
%x,%x,%x\n",
+           protect_p ? "" : "un", th,
+           CONTROL_STACK_GUARD_PAGE(th),
+           os_vm_page_size,protect_p ?
+           (OS_VM_PROT_READ|OS_VM_PROT_EXECUTE) : OS_VM_PROT_ALL);
+
+    os_protect(CONTROL_STACK_GUARD_PAGE(th),
               os_vm_page_size,protect_p ?
               (OS_VM_PROT_READ|OS_VM_PROT_EXECUTE) : OS_VM_PROT_ALL);
-    */
 }
 

Index: validate.h
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/validate.h,v
retrieving revision 1.7.4.1
retrieving revision 1.7.4.2
diff -u -d -r1.7.4.1 -r1.7.4.2
--- validate.h  24 Nov 2002 13:14:17 -0000      1.7.4.1
+++ validate.h  18 Dec 2002 17:23:45 -0000      1.7.4.2
@@ -19,15 +19,16 @@
 #define    STATIC_SPACE_SIZE (   STATIC_SPACE_END -    STATIC_SPACE_START)
 #define THREAD_CONTROL_STACK_SIZE (2*1024*1024)        /* wired 
elsewhere-watch out */
 
+#if !defined(LANGUAGE_ASSEMBLY)
+#include <thread.h>
 #ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD 
-#define CONTROL_STACK_GUARD_PAGE (CONTROL_STACK_START)
+#define CONTROL_STACK_GUARD_PAGE(th) ((void *)(th->control_stack_start))
 #else
-#define CONTROL_STACK_GUARD_PAGE (CONTROL_STACK_END - os_vm_page_size)
+#define CONTROL_STACK_GUARD_PAGE(th) (((void 
*)(th->control_stack_start))+THREAD_CONTROL_STACK_SIZE - os_vm_page_size)
 #endif
 
-#if !defined(LANGUAGE_ASSEMBLY)
 extern void validate(void);
-extern void protect_control_stack_guard_page(int protect_p);
+extern void protect_control_stack_guard_page(struct thread *th,int protect_p);
 #endif
 
 /* note for anyone trying to port an architecture's support files

Index: x86-linux-os.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-linux-os.c,v
retrieving revision 1.7.4.4
retrieving revision 1.7.4.5
diff -u -d -r1.7.4.4 -r1.7.4.5
--- x86-linux-os.c      13 Dec 2002 02:03:27 -0000      1.7.4.4
+++ x86-linux-os.c      18 Dec 2002 17:23:45 -0000      1.7.4.5
@@ -60,6 +60,7 @@
     /* this must be called from a function that has an exclusive lock
      * on all_threads
      */
+    stack_t sigstack;
     struct modify_ldt_ldt_s ldt_entry = {
        1, 0, 0, /* index, address, length filled in later */
        1, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 1
@@ -85,6 +86,16 @@
                           + (1 << 2) /* TI set = LDT */
                           + 3)); /* privilege level */
     thread->tls_cookie=n;
+    if(n<0) return 0;
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+    /* Signal handlers are run on the control stack, so if it is exhausted
+     * we had better use an alternate stack for whatever signal tells us
+     * we've exhausted it */
+    sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
+    sigstack.ss_flags=0;
+    sigstack.ss_size = 32*SIGSTKSZ;
+    sigaltstack(&sigstack,0);
+#endif
     return (n>=0);
 }
 



-------------------------------------------------------
This SF.NET email is sponsored by: Order your Holiday Geek Presents Now!
Green Lasers, Hip Geek T-Shirts, Remote Control Tanks, Caffeinated Soap,
MP3 Players,  XBox Games,  Flying Saucers,  WebCams,  Smart Putty.
T H I N K G E E K . C O M       http://www.thinkgeek.com/sf/



Try Searching:
servers, voip, java, networking, microsoft ...
<Prev in Thread] Current Thread [Next in Thread>