changeset 78437:77430fdfce38

(_malloc_thread_enabled_p) [USE_PTHREAD]: New variable. [USE_PTHREAD] (LOCK, UNLOCK, LOCK_ALIGNED_BLOCKS) (UNLOCK_ALIGNED_BLOCKS): Conditionalize with it. (malloc_atfork_handler_prepare, malloc_atfork_handler_parent) (malloc_atfork_handler_child, malloc_enable_thread) [USE_PTHREAD]: New functions.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Tue, 07 Aug 2007 08:57:24 +0000
parents 34b7a05ac98e
children 0e453038c2da
files src/gmalloc.c
diffstat 1 files changed, 66 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/gmalloc.c	Tue Aug 07 08:57:06 2007 +0000
+++ b/src/gmalloc.c	Tue Aug 07 08:57:24 2007 +0000
@@ -136,6 +136,10 @@
 extern __ptr_t valloc PP ((__malloc_size_t __size));
 #endif
 
+#ifdef USE_PTHREAD
+/* Set up mutexes and make malloc etc. thread-safe.  */
+extern void malloc_enable_thread PP ((void));
+#endif
 
 #ifdef _MALLOC_INTERNAL
 
@@ -242,10 +246,27 @@
 
 #ifdef USE_PTHREAD
 extern pthread_mutex_t _malloc_mutex, _aligned_blocks_mutex;
-#define LOCK()     pthread_mutex_lock (&_malloc_mutex)
-#define UNLOCK()   pthread_mutex_unlock (&_malloc_mutex)
-#define LOCK_ALIGNED_BLOCKS()     pthread_mutex_lock (&_aligned_blocks_mutex)
-#define UNLOCK_ALIGNED_BLOCKS()   pthread_mutex_unlock (&_aligned_blocks_mutex)
+extern int _malloc_thread_enabled_p;
+#define LOCK()					\
+  do {						\
+    if (_malloc_thread_enabled_p)		\
+      pthread_mutex_lock (&_malloc_mutex);	\
+  } while (0)
+#define UNLOCK()				\
+  do {						\
+    if (_malloc_thread_enabled_p)		\
+      pthread_mutex_unlock (&_malloc_mutex);	\
+  } while (0)
+#define LOCK_ALIGNED_BLOCKS()				\
+  do {							\
+    if (_malloc_thread_enabled_p)			\
+      pthread_mutex_lock (&_aligned_blocks_mutex);	\
+  } while (0)
+#define UNLOCK_ALIGNED_BLOCKS()				\
+  do {							\
+    if (_malloc_thread_enabled_p)			\
+      pthread_mutex_unlock (&_aligned_blocks_mutex);	\
+  } while (0)
 #else
 #define LOCK()
 #define UNLOCK()
@@ -564,6 +585,47 @@
 static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT;
 pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER;
+int _malloc_thread_enabled_p;
+
+static void
+malloc_atfork_handler_prepare ()
+{
+  LOCK ();
+  LOCK_ALIGNED_BLOCKS ();
+}
+
+static void
+malloc_atfork_handler_parent ()
+{
+  UNLOCK_ALIGNED_BLOCKS ();
+  UNLOCK ();
+}
+
+static void
+malloc_atfork_handler_child ()
+{
+  UNLOCK_ALIGNED_BLOCKS ();
+  UNLOCK ();
+}
+
+/* Set up mutexes and make malloc etc. thread-safe.  */
+void
+malloc_enable_thread ()
+{
+  if (_malloc_thread_enabled_p)
+    return;
+
+  /* Some pthread implementations call malloc for statically
+     initialized mutexes when they are used first.  To avoid such a
+     situation, we initialize mutexes here while their use is
+     disabled in malloc etc.  */
+  pthread_mutex_init (&_malloc_mutex, NULL);
+  pthread_mutex_init (&_aligned_blocks_mutex, NULL);
+  pthread_atfork (malloc_atfork_handler_prepare,
+		  malloc_atfork_handler_parent,
+		  malloc_atfork_handler_child);
+  _malloc_thread_enabled_p = 1;
+}
 #endif
 
 static void
@@ -576,19 +638,6 @@
   if (__malloc_initialize_hook)
     (*__malloc_initialize_hook) ();
 
-  /* We don't use recursive mutex because pthread_mutexattr_init may
-     call malloc internally.  */
-#if 0 /* defined (USE_PTHREAD) */
-  {
-    pthread_mutexattr_t attr;
-
-    pthread_mutexattr_init (&attr);
-    pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init (&_malloc_mutex, &attr);
-    pthread_mutexattr_destroy (&attr);
-  }
-#endif
-
   heapsize = HEAP / BLOCKSIZE;
   _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info));
   if (_heapinfo == NULL)