Started rewriting thread state machine.
Malcolm Beattie [Wed, 15 Oct 1997 09:09:24 +0000 (09:09 +0000)]
p4raw-id: //depot/perl@125

perl.c
thread.h

diff --git a/perl.c b/perl.c
index 4897da0..dea0cfd 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -132,7 +132,8 @@ register PerlInterpreter *sv_interp;
        nthreads = 1;
        cvcache = newHV();
        curcop = &compiling;
-       thr->flags = THRf_NORMAL;
+       thr->flags = THRf_R_JOINABLE;
+       MUTEX_INIT(&thr->mutex);
        thr->next = thr;
        thr->prev = thr;
 #ifdef FAKE_THREADS
@@ -240,16 +241,25 @@ register PerlInterpreter *sv_interp;
 
 #ifdef USE_THREADS
 #ifndef FAKE_THREADS
-    /* Detach any remaining joinable threads apart from ourself */
+    /* Join with any remaining non-detached threads */
     MUTEX_LOCK(&threads_mutex);
     DEBUG_L(PerlIO_printf(PerlIO_stderr(),
-                         "perl_destruct: detaching remaining %d threads\n",
+                         "perl_destruct: waiting for %d threads\n",
                          nthreads - 1));
     for (t = thr->next; t != thr; t = t->next) {
-       if (ThrSTATE(t) == THRf_NORMAL) {
-           DETACH(t);
-           ThrSETSTATE(t, THRf_DETACHED);
-           DEBUG_L(PerlIO_printf(PerlIO_stderr(), "...detached %p\n", t));
+       MUTEX_LOCK(&t->mutex);
+       switch (ThrSTATE(t)) {
+           AV *av;
+       case R_ZOMBIE:
+           ThrSETSTATE(t, THRf_DEAD);
+           MUTEX_UNLOCK(&t->mutex);
+           nthreads--;
+           MUTEX_UNLOCK(&threads_mutex);
+           if (pthread_join(t->Tself, (void**)&av))
+               croak("panic: pthread_join failed during global destruction");
+           SvREFCNT_dec((SV*)av);
+           break;
+       case XXXX:
        }
     }
     /* Now wait for the thread count nthreads to drop to one */
index f379f6b..4bea061 100644 (file)
--- a/thread.h
+++ b/thread.h
@@ -159,9 +159,9 @@ struct thread {
 
     perl_thread        Tself;
     SV *       Toursv;
-    perl_mutex *Tthreadstart_mutexp;
     HV *       Tcvcache;
     U32                flags;
+    perl_mutex mutex;
     U32                tid;
     struct thread *next, *prev;                /* Circular linked list of threads */
 
@@ -176,20 +176,23 @@ struct thread {
 typedef struct thread *Thread;
 
 /* Values and macros for thr->flags */
-#define THRf_STATE_MASK        3
-#define THRf_NORMAL    0
-#define THRf_DETACHED  1
-#define THRf_JOINED    2
-#define THRf_DEAD      3
+#define THRf_STATE_MASK        7
+#define THRf_R_JOINABLE        0
+#define THRf_R_JOINED  1
+#define THRf_R_DETACHED        2
+#define THRf_ZOMBIE    3
+#define THRf_DEAD      4
 
-#define THRf_DIE_FATAL 4
+#define THRf_DIE_FATAL 8
 
-#define ThrSTATE(t)    (t->flags & THRf_STATE_MASK)
+#define ThrSTATE(t) ((t)->flags)
 #define ThrSETSTATE(t, s) STMT_START {         \
-       (t)->flags &= ~THRf_STATE_MASK; \
+       MUTEX_LOCK(&(t)->mutex);                \
+       (t)->flags &= ~THRf_STATE_MASK;         \
        (t)->flags |= (s);                      \
-       DEBUG_L(fprintf(stderr, "thread 0x%lx set to state %d\n", \
-                       (unsigned long)(t), (s))); \
+       MUTEX_UNLOCK(&(t)->mutex);              \
+       DEBUG_L(PerlIO_printf(PerlIO_stderr(),  \
+                             "thread %p set to state %d\n", (t), (s))); \
     } STMT_END
 
 typedef struct condpair {
@@ -300,6 +303,5 @@ typedef struct condpair {
 #define        top_env         (thr->Ttop_env)
 #define        runlevel        (thr->Trunlevel)
 
-#define        threadstart_mutexp      (thr->Tthreadstart_mutexp)
 #define        cvcache         (thr->Tcvcache)
 #endif /* USE_THREADS */