0.9.3.34: cosmetics
[sbcl.git] / src / runtime / thread.c
index 4b39120..adeada3 100644 (file)
@@ -10,7 +10,7 @@
 
 #include "sbcl.h"
 #include "runtime.h"
-#include "validate.h"          /* for CONTROL_STACK_SIZE etc */
+#include "validate.h"           /* for CONTROL_STACK_SIZE etc */
 #include "alloc.h"
 #include "thread.h"
 #include "arch.h"
 
 #define ALIEN_STACK_SIZE (1*1024*1024) /* 1Mb size chosen at random */
 
-int dynamic_values_bytes=4096*sizeof(lispobj); /* same for all threads */
+int dynamic_values_bytes=4096*sizeof(lispobj);  /* same for all threads */
 struct thread *all_threads;
 volatile lispobj all_threads_lock;
 extern struct interrupt_data * global_interrupt_data;
 extern int linux_no_threads_p;
 
+#ifdef LISP_FEATURE_SB_THREAD
 /* When trying to get all_threads_lock one should make sure that
  * sig_stop_for_gc is not blocked. Else there would be a possible
  * deadlock: gc locks it, other thread blocks signals, gc sends stop
@@ -42,19 +43,13 @@ void check_sig_stop_for_gc_can_arrive_or_lose()
     sigemptyset(&empty);
     thread_sigmask(SIG_BLOCK, &empty, &current);
     if (sigismember(&current,SIG_STOP_FOR_GC))
-        lose("SIG_STOP_FOR_GC is blocked\n");
+        lose("SIG_STOP_FOR_GC cannot arrive: it is blocked\n");
     if (SymbolValue(INTERRUPTS_ENABLED,arch_os_get_current_thread()) == NIL)
-        lose("interrupts disabled\n");
+        lose("SIG_STOP_FOR_GC cannot arrive: interrupts disabled\n");
     if (arch_pseudo_atomic_atomic(NULL))
-        lose("n pseudo atomic\n");
+        lose("SIG_STOP_FOR_GC cannot arrive: in pseudo atomic\n");
 }
 
-#ifdef QSHOW_SIGNALS
-#define FSHOW_SIGNAL FSHOW
-#else
-#define FSHOW_SIGNAL(args)
-#endif
-
 #define GET_ALL_THREADS_LOCK(name) \
     { \
         sigset_t _newset,_oldset; \
@@ -63,10 +58,10 @@ void check_sig_stop_for_gc_can_arrive_or_lose()
         sigdelset(&_newset,SIG_STOP_FOR_GC); \
         thread_sigmask(SIG_BLOCK, &_newset, &_oldset); \
         check_sig_stop_for_gc_can_arrive_or_lose(); \
-        FSHOW_SIGNAL((stderr,"/%s:waiting on lock=%ld, thread=%ld\n",name, \
+        FSHOW_SIGNAL((stderr,"/%s:waiting on lock=%ld, thread=%lu\n",name, \
                all_threads_lock,arch_os_get_current_thread()->os_thread)); \
         get_spinlock(&all_threads_lock,(long)arch_os_get_current_thread()); \
-        FSHOW_SIGNAL((stderr,"/%s:got lock, thread=%ld\n", \
+        FSHOW_SIGNAL((stderr,"/%s:got lock, thread=%lu\n", \
                name,arch_os_get_current_thread()->os_thread));
 
 #define RELEASE_ALL_THREADS_LOCK(name) \
@@ -74,6 +69,12 @@ void check_sig_stop_for_gc_can_arrive_or_lose()
         release_spinlock(&all_threads_lock); \
         thread_sigmask(SIG_SETMASK,&_oldset,0); \
     }
+#endif
+
+
+#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
+extern lispobj call_into_lisp_first_time(lispobj fun, lispobj *args, int nargs);
+#endif
 
 int
 initial_thread_trampoline(struct thread *th)
@@ -82,7 +83,6 @@ initial_thread_trampoline(struct thread *th)
 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
     lispobj *args = NULL;
 #endif
-
     function = th->unbound_marker;
     th->unbound_marker = UNBOUND_MARKER_WIDETAG;
     if(arch_os_thread_init(th)==0) return 1;
@@ -126,52 +126,52 @@ new_thread_trampoline(struct thread *th)
 
 struct thread * create_thread_struct(lispobj initial_function) {
     union per_thread_data *per_thread;
-    struct thread *th=0;       /*  subdue gcc */
+    struct thread *th=0;        /*  subdue gcc */
     void *spaces=0;
 
     /* may as well allocate all the spaces at once: it saves us from
      * 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+
-                      32*SIGSTKSZ);
+                       THREAD_CONTROL_STACK_SIZE+
+                       BINDING_STACK_SIZE+
+                       ALIEN_STACK_SIZE+
+                       dynamic_values_bytes+
+                       32*SIGSTKSZ);
     if(!spaces)
-        return NULL;
+         return NULL;
     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);
 
     if(all_threads) {
-       memcpy(per_thread,arch_os_get_current_thread(),
-              dynamic_values_bytes);
+        memcpy(per_thread,arch_os_get_current_thread(),
+               dynamic_values_bytes);
     } else {
 #ifdef LISP_FEATURE_SB_THREAD
-       int i;
-       for(i=0;i<(dynamic_values_bytes/sizeof(lispobj));i++)
-           per_thread->dynamic_values[i]=UNBOUND_MARKER_WIDETAG;
-       if(SymbolValue(FREE_TLS_INDEX,0)==UNBOUND_MARKER_WIDETAG)
-           SetSymbolValue
-               (FREE_TLS_INDEX,
-                make_fixnum(MAX_INTERRUPTS+
-                            sizeof(struct thread)/sizeof(lispobj)),
-                0);
+        int i;
+        for(i=0;i<(dynamic_values_bytes/sizeof(lispobj));i++)
+            per_thread->dynamic_values[i]=UNBOUND_MARKER_WIDETAG;
+        if(SymbolValue(FREE_TLS_INDEX,0)==UNBOUND_MARKER_WIDETAG)
+            SetSymbolValue
+                (FREE_TLS_INDEX,
+                 make_fixnum(MAX_INTERRUPTS+
+                             sizeof(struct thread)/sizeof(lispobj)),
+                 0);
 #define STATIC_TLS_INIT(sym,field) \
   ((struct symbol *)(sym-OTHER_POINTER_LOWTAG))->tls_index= \
   make_fixnum(THREAD_SLOT_OFFSET_WORDS(field))
 
-       STATIC_TLS_INIT(BINDING_STACK_START,binding_stack_start);
-       STATIC_TLS_INIT(BINDING_STACK_POINTER,binding_stack_pointer);
-       STATIC_TLS_INIT(CONTROL_STACK_START,control_stack_start);
-       STATIC_TLS_INIT(CONTROL_STACK_END,control_stack_end);
-       STATIC_TLS_INIT(ALIEN_STACK,alien_stack_pointer);
+        STATIC_TLS_INIT(BINDING_STACK_START,binding_stack_start);
+        STATIC_TLS_INIT(BINDING_STACK_POINTER,binding_stack_pointer);
+        STATIC_TLS_INIT(CONTROL_STACK_START,control_stack_start);
+        STATIC_TLS_INIT(CONTROL_STACK_END,control_stack_end);
+        STATIC_TLS_INIT(ALIEN_STACK,alien_stack_pointer);
 #if defined(LISP_FEATURE_X86) || defined (LISP_FEATURE_X86_64)
-       STATIC_TLS_INIT(PSEUDO_ATOMIC_ATOMIC,pseudo_atomic_atomic);
-       STATIC_TLS_INIT(PSEUDO_ATOMIC_INTERRUPTED,pseudo_atomic_interrupted);
+        STATIC_TLS_INIT(PSEUDO_ATOMIC_ATOMIC,pseudo_atomic_atomic);
+        STATIC_TLS_INIT(PSEUDO_ATOMIC_INTERRUPTED,pseudo_atomic_interrupted);
 #endif
 #undef STATIC_TLS_INIT
 #endif
@@ -180,10 +180,10 @@ struct thread * create_thread_struct(lispobj initial_function) {
     th=&per_thread->thread;
     th->control_stack_start = spaces;
     th->binding_stack_start=
-       (lispobj*)((void*)th->control_stack_start+THREAD_CONTROL_STACK_SIZE);
+        (lispobj*)((void*)th->control_stack_start+THREAD_CONTROL_STACK_SIZE);
     th->control_stack_end = th->binding_stack_start;
     th->alien_stack_start=
-       (lispobj*)((void*)th->binding_stack_start+BINDING_STACK_SIZE);
+        (lispobj*)((void*)th->binding_stack_start+BINDING_STACK_SIZE);
     th->binding_stack_pointer=th->binding_stack_start;
     th->this=th;
     th->os_thread=0;
@@ -192,7 +192,7 @@ struct thread * create_thread_struct(lispobj initial_function) {
     th->state=STATE_STARTING;
 #ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD
     th->alien_stack_pointer=((void *)th->alien_stack_start
-                            + ALIEN_STACK_SIZE-N_WORD_BYTES);
+                             + ALIEN_STACK_SIZE-N_WORD_BYTES);
 #else
     th->alien_stack_pointer=((void *)th->alien_stack_start);
 #endif
@@ -233,12 +233,12 @@ struct thread * create_thread_struct(lispobj initial_function) {
     th->interrupt_data = (struct interrupt_data *)
         os_validate(0,(sizeof (struct interrupt_data)));
     if(all_threads)
-       memcpy(th->interrupt_data,
-              arch_os_get_current_thread()->interrupt_data,
-              sizeof (struct interrupt_data));
+        memcpy(th->interrupt_data,
+               arch_os_get_current_thread()->interrupt_data,
+               sizeof (struct interrupt_data));
     else
-       memcpy(th->interrupt_data,global_interrupt_data,
-              sizeof (struct interrupt_data));
+        memcpy(th->interrupt_data,global_interrupt_data,
+               sizeof (struct interrupt_data));
 
     th->unbound_marker=initial_function;
     return th;
@@ -263,13 +263,18 @@ void create_initial_thread(lispobj initial_function) {
     struct thread *th=create_thread_struct(initial_function);
     os_thread_t kid_tid=thread_self();
     if(th && kid_tid>0) {
-       link_thread(th,kid_tid);
-       initial_thread_trampoline(all_threads); /* no return */
+        link_thread(th,kid_tid);
+        initial_thread_trampoline(all_threads); /* no return */
     } else lose("can't create initial thread");
 }
 
 #ifdef LISP_FEATURE_SB_THREAD
 
+#ifndef __USE_XOPEN2K
+extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
+                                  size_t __stacksize);
+#endif
+
 boolean create_os_thread(struct thread *th,os_thread_t *kid_tid)
 {
     /* The new thread inherits the restrictive signal mask set here,
@@ -280,7 +285,7 @@ boolean create_os_thread(struct thread *th,os_thread_t *kid_tid)
     sigemptyset(&newset);
     sigaddset_blockable(&newset);
     thread_sigmask(SIG_BLOCK, &newset, &oldset);
-    
+
     if((pthread_attr_init(&attr)) ||
        (pthread_attr_setstack(&attr,th->control_stack_start,
                               THREAD_CONTROL_STACK_SIZE-16)) ||
@@ -308,13 +313,13 @@ struct thread *create_thread(lispobj initial_function) {
 
     success=create_os_thread(th,&kid_tid);
     if (success)
-       link_thread(th,kid_tid);
+        link_thread(th,kid_tid);
     else
-       os_invalidate((os_vm_address_t) th->control_stack_start,
-                     ((sizeof (lispobj))
-                      * (th->control_stack_end-th->control_stack_start)) +
-                     BINDING_STACK_SIZE+ALIEN_STACK_SIZE+dynamic_values_bytes+
-                     32*SIGSTKSZ);
+        os_invalidate((os_vm_address_t) th->control_stack_start,
+                      ((sizeof (lispobj))
+                       * (th->control_stack_end-th->control_stack_start)) +
+                      BINDING_STACK_SIZE+ALIEN_STACK_SIZE+dynamic_values_bytes+
+                      32*SIGSTKSZ);
 
     RELEASE_ALL_THREADS_LOCK("create_thread")
 
@@ -323,17 +328,12 @@ struct thread *create_thread(lispobj initial_function) {
     else
         return 0;
 }
-#endif
-
-#if defined LISP_FEATURE_SB_THREAD
-/* This is not needed unless #+SB-THREAD, as there's a trivial null
- * unithread definition. */
 
 /* called from lisp from the thread object finalizer */
 void reap_dead_thread(struct thread *th)
 {
     if(th->state!=STATE_DEAD)
-        lose("thread %lx is not joinable, state=%d\n",th,th->state);
+        lose("thread %p is not joinable, state=%d\n",th,th->state);
 #ifdef LISP_FEATURE_GENCGC
     {
         sigset_t newset,oldset;
@@ -346,7 +346,7 @@ void reap_dead_thread(struct thread *th)
     }
 #endif
     GET_ALL_THREADS_LOCK("reap_dead_thread")
-    FSHOW((stderr,"/reap_dead_thread: reaping %ld\n",th->os_thread));
+    FSHOW((stderr,"/reap_dead_thread: reaping %lu\n",th->os_thread));
     if(th->prev)
         th->prev->next=th->next;
     else all_threads=th->next;
@@ -380,12 +380,13 @@ int interrupt_thread(struct thread *th, lispobj function)
          * interrupt_fun data for exactly as many signals as are
          * going to be received by the destination thread.
          */
-        struct cons *c=alloc_cons(function,NIL);
+        lispobj c=alloc_cons(function,NIL);
         int kill_status;
         /* interrupt_thread_handler locks this spinlock with
-         * interrupts blocked and it does so for the sake of
-         * arrange_return_to_lisp_function, so we must also block
-         * them. */
+         * interrupts blocked (it does so for the sake of
+         * arrange_return_to_lisp_function), so we must also block
+         * them or else SIG_STOP_FOR_GC and all_threads_lock will find
+         * a way to deadlock. */
         sigset_t newset,oldset;
         sigemptyset(&newset);
         sigaddset_blockable(&newset);
@@ -416,23 +417,23 @@ int interrupt_thread(struct thread *th, lispobj function)
 void gc_stop_the_world()
 {
     struct thread *p,*th=arch_os_get_current_thread();
-    FSHOW_SIGNAL((stderr,"/gc_stop_the_world:waiting on lock, thread=%ld\n",
+    FSHOW_SIGNAL((stderr,"/gc_stop_the_world:waiting on lock, thread=%lu\n",
                   th->os_thread));
     /* keep threads from starting while the world is stopped. */
     get_spinlock(&all_threads_lock,(long)th);
-    FSHOW_SIGNAL((stderr,"/gc_stop_the_world:got lock, thread=%ld\n",
+    FSHOW_SIGNAL((stderr,"/gc_stop_the_world:got lock, thread=%lu\n",
                   th->os_thread));
     /* stop all other threads by sending them SIG_STOP_FOR_GC */
     for(p=all_threads; p; p=p->next) {
         while(p->state==STATE_STARTING) sched_yield();
         if((p!=th) && (p->state==STATE_RUNNING)) {
-            FSHOW_SIGNAL((stderr,"/gc_stop_the_world:sending sig_stop to %ld\n",
+            FSHOW_SIGNAL((stderr, "/gc_stop_the_world: suspending %lu\n",
                           p->os_thread));
             if(thread_kill(p->os_thread,SIG_STOP_FOR_GC)==-1) {
                 /* we can't kill the thread; assume because it died
                  * since we last checked */
                 p->state=STATE_DEAD;
-                FSHOW_SIGNAL((stderr,"/gc_stop_the_world:assuming %ld dead\n",
+                FSHOW_SIGNAL((stderr,"/gc_stop_the_world:assuming %lu dead\n",
                    p->os_thread));
             }
         }
@@ -460,15 +461,17 @@ void gc_start_the_world()
     FSHOW_SIGNAL((stderr,"/gc_start_the_world:begin\n"));
     for(p=all_threads;p;p=p->next) {
         gc_assert(p->os_thread!=0);
-       if((p!=th) && (p->state!=STATE_DEAD)) {
+        if((p!=th) && (p->state!=STATE_DEAD)) {
             if(p->state!=STATE_SUSPENDED) {
-                lose("gc_start_the_world: wrong thread state is %ld\n",
+                lose("gc_start_the_world: wrong thread state is %d\n",
                      fixnum_value(p->state));
             }
+            FSHOW_SIGNAL((stderr, "/gc_start_the_world: resuming %lu\n",
+                          p->os_thread));
             thread_kill(p->os_thread,SIG_STOP_FOR_GC);
         }
     }
-    /* we must wait for all threads to leave stopped state else we
+    /* we must wait for all threads to leave suspended state else we
      * risk signal accumulation and lose any meaning of
      * thread->state */
     for(p=all_threads;p;) {