provide locked access to string table for USE_THREADS
Gurusamy Sarathy [Thu, 24 Sep 1998 03:36:30 +0000 (03:36 +0000)]
p4raw-id: //depot/perl@1863

embedvar.h
hv.c
intrpvar.h
objXSUB.h
perl.c
thread.h

index 8c1b786..be36de0 100644 (file)
 #define PL_stdingv             (PL_curinterp->Istdingv)
 #define PL_strchop             (PL_curinterp->Istrchop)
 #define PL_strtab              (PL_curinterp->Istrtab)
+#define PL_strtab_mutex                (PL_curinterp->Istrtab_mutex)
 #define PL_sub_generation      (PL_curinterp->Isub_generation)
 #define PL_sublex_info         (PL_curinterp->Isublex_info)
 #define PL_sv_arenaroot                (PL_curinterp->Isv_arenaroot)
 #define PL_Istdingv            PL_stdingv
 #define PL_Istrchop            PL_strchop
 #define PL_Istrtab             PL_strtab
+#define PL_Istrtab_mutex       PL_strtab_mutex
 #define PL_Isub_generation     PL_sub_generation
 #define PL_Isublex_info                PL_sublex_info
 #define PL_Isv_arenaroot       PL_sv_arenaroot
diff --git a/hv.c b/hv.c
index 40bb9b8..2416831 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1149,6 +1149,7 @@ unsharepvn(char *str, I32 len, U32 hash)
     } */
     xhv = (XPVHV*)SvANY(PL_strtab);
     /* assert(xhv_array != 0) */
+    LOCK_STRTAB_MUTEX;
     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
     for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
@@ -1166,6 +1167,7 @@ unsharepvn(char *str, I32 len, U32 hash)
            del_he(entry);
            --xhv->xhv_keys;
        }
+       UNLOCK_STRTAB_MUTEX;
        break;
     }
     
@@ -1193,6 +1195,7 @@ share_hek(char *str, I32 len, register U32 hash)
     */
     xhv = (XPVHV*)SvANY(PL_strtab);
     /* assert(xhv_array != 0) */
+    LOCK_STRTAB_MUTEX;
     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
        if (HeHASH(entry) != hash)              /* strings can't be equal */
@@ -1219,6 +1222,7 @@ share_hek(char *str, I32 len, register U32 hash)
     }
 
     ++HeVAL(entry);                            /* use value slot as REFCNT */
+    UNLOCK_STRTAB_MUTEX;
     return HeKEY_hek(entry);
 }
 
index dfdcca8..1f6244d 100644 (file)
@@ -199,6 +199,7 @@ PERLVAR(Isublex_info,       SUBLEXINFO)     /* from toke.c */
 #ifdef USE_THREADS
 PERLVAR(Ithrsv,                SV *)           /* struct perl_thread for main thread */
 PERLVARI(Ithreadnum,   U32,    0)      /* incremented each thread creation */
+PERLVAR(Istrtab_mutex, perl_mutex)     /* Mutex for string table access */
 #endif /* USE_THREADS */
 
 PERLVARI(Ibytecode_iv_overflows,int,   0)      /* from bytecode.h */
index 2c43839..116075b 100644 (file)
--- a/objXSUB.h
+++ b/objXSUB.h
 #define PL_strchop                             pPerl->PL_strchop               
 #undef  PL_strtab              
 #define PL_strtab                              pPerl->PL_strtab                
+#undef  PL_strtab_mutex
+#define PL_strtab_mutex                                pPerl->PL_strtab_mutex
 #undef  PL_sub_generation      
 #define PL_sub_generation              pPerl->PL_sub_generation        
 #undef  PL_sublex_info         
diff --git a/perl.c b/perl.c
index 79fab4a..a5bb536 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -553,6 +553,7 @@ perl_destruct(register PerlInterpreter *sv_interp)
     
     DEBUG_P(debprofdump());
 #ifdef USE_THREADS
+    MUTEX_DESTROY(&PL_strtab_mutex);
     MUTEX_DESTROY(&PL_sv_mutex);
     MUTEX_DESTROY(&PL_eval_mutex);
     COND_DESTROY(&PL_eval_cond);
@@ -1905,6 +1906,9 @@ init_main_stash(void)
        about not iterating on it, and not adding tie magic to it.
        It is properly deallocated in perl_destruct() */
     PL_strtab = newHV();
+#ifdef USE_THREADS
+    MUTEX_INIT(&PL_strtab_mutex);
+#endif
     HvSHAREKEYS_off(PL_strtab);                        /* mandatory */
     hv_ksplit(PL_strtab, 512);
     
index 3eb061a..035c5ca 100644 (file)
--- a/thread.h
+++ b/thread.h
@@ -161,16 +161,29 @@ struct perl_thread *getTHR _((void));
  * Systems with very fast mutexes (and/or slow conditionals) may wish to
  * remove the "if (threadnum) ..." test.
  */
-#define LOCK_SV_MUTEX                  \
-    STMT_START {                       \
+#define LOCK_SV_MUTEX                          \
+    STMT_START {                               \
+       if (PL_threadnum)                       \
+           MUTEX_LOCK(&PL_sv_mutex);           \
+    } STMT_END
+
+#define UNLOCK_SV_MUTEX                                \
+    STMT_START {                               \
        if (PL_threadnum)                       \
-           MUTEX_LOCK(&PL_sv_mutex);   \
+           MUTEX_UNLOCK(&PL_sv_mutex);         \
     } STMT_END
 
-#define UNLOCK_SV_MUTEX                        \
-    STMT_START {                       \
+/* Likewise for strtab_mutex */
+#define LOCK_STRTAB_MUTEX                      \
+    STMT_START {                               \
+       if (PL_threadnum)                       \
+           MUTEX_LOCK(&PL_strtab_mutex);       \
+    } STMT_END
+
+#define UNLOCK_STRTAB_MUTEX                    \
+    STMT_START {                               \
        if (PL_threadnum)                       \
-           MUTEX_UNLOCK(&PL_sv_mutex); \
+           MUTEX_UNLOCK(&PL_strtab_mutex);     \
     } STMT_END
 
 #ifndef THREAD_RET_TYPE
@@ -223,6 +236,8 @@ typedef struct condpair {
 #define COND_DESTROY(c)
 #define LOCK_SV_MUTEX
 #define UNLOCK_SV_MUTEX
+#define LOCK_STRTAB_MUTEX
+#define UNLOCK_STRTAB_MUTEX
 
 #define THR
 /* Rats: if dTHR is just blank then the subsequent ";" throws an error */