changeset 76776:2bb28b957639

[HAVE_GTK_AND_PTHREAD]: Define USE_PTHREAD. [USE_PTHREAD]: Include pthread.h. (malloc_init_once_control, _malloc_mutex) [USE_PTHREAD]: New variables. (malloc_initialize_1): New function created from __malloc_initialize. (__malloc_initialize): Use it. (LOCK, UNLOCK): New macros to make malloc etc. thread safe. (_malloc_internal, _free_internal, _realloc_internal): Use them.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Wed, 28 Mar 2007 08:16:05 +0000
parents 3891e219df10
children 846cbca78bc8
files src/gmalloc.c
diffstat 1 files changed, 65 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/gmalloc.c	Wed Mar 28 08:15:27 2007 +0000
+++ b/src/gmalloc.c	Wed Mar 28 08:16:05 2007 +0000
@@ -1,6 +1,9 @@
 /* This file is no longer automatically generated from libc.  */
 
 #define _MALLOC_INTERNAL
+#ifdef HAVE_GTK_AND_PTHREAD
+#define USE_PTHREAD
+#endif
 
 /* The malloc headers and source files from the C library follow here.  */
 
@@ -73,6 +76,10 @@
 #include <unistd.h>
 #endif
 
+#ifdef USE_PTHREAD
+#include <pthread.h>
+#endif
+
 #endif	/* _MALLOC_INTERNAL.  */
 
 
@@ -229,6 +236,15 @@
 extern __ptr_t _realloc_internal PP ((__ptr_t __ptr, __malloc_size_t __size));
 extern void _free_internal PP ((__ptr_t __ptr));
 
+#ifdef USE_PTHREAD
+extern pthread_mutex_t _malloc_mutex;
+#define LOCK()     pthread_mutex_lock (&_malloc_mutex)
+#define UNLOCK()   pthread_mutex_unlock (&_malloc_mutex)
+#else
+#define LOCK()
+#define UNLOCK()
+#endif
+
 #endif /* _MALLOC_INTERNAL.  */
 
 /* Given an address in the middle of a malloc'd object,
@@ -536,13 +552,14 @@
     _heapinfo[block + blocks].busy.info.size = -blocks;
 }
 
-/* Set everything up and remember that we have.  */
-int
-__malloc_initialize ()
+#ifdef USE_PTHREAD
+static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT;
+pthread_mutex_t _malloc_mutex;
+#endif
+
+static void
+malloc_initialize_1 ()
 {
-  if (__malloc_initialized)
-    return 0;
-
 #ifdef GC_MCHECK
   mcheck (NULL);
 #endif
@@ -550,10 +567,21 @@
   if (__malloc_initialize_hook)
     (*__malloc_initialize_hook) ();
 
+#ifdef 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)
-    return 0;
+    return;
   memset (_heapinfo, 0, heapsize * sizeof (malloc_info));
   _heapinfo[0].free.size = 0;
   _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
@@ -565,7 +593,23 @@
 
   __malloc_initialized = 1;
   PROTECT_MALLOC_STATE (1);
-  return 1;
+  return;
+}
+
+/* Set everything up and remember that we have.  */
+int
+__malloc_initialize ()
+{
+#ifdef USE_PTHREAD
+  pthread_once (&malloc_init_once_control, malloc_initialize_1);
+#else
+  if (__malloc_initialized)
+    return 0;
+
+  malloc_initialize_1 ();
+#endif
+
+  return __malloc_initialized;
 }
 
 static int morecore_recursing;
@@ -708,6 +752,7 @@
     return NULL;
 #endif
 
+  LOCK ();
   PROTECT_MALLOC_STATE (0);
 
   if (size < sizeof (struct list))
@@ -765,7 +810,7 @@
 	  if (result == NULL)
 	    {
 	      PROTECT_MALLOC_STATE (1);
-	      return NULL;
+	      goto out;
 	    }
 
 	  /* Link all fragments but the first into the free list.  */
@@ -831,7 +876,7 @@
 		}
 	      result = morecore (wantblocks * BLOCKSIZE);
 	      if (result == NULL)
-		return NULL;
+		goto out;
 	      block = BLOCK (result);
 	      /* Put the new block at the end of the free list.  */
 	      _heapinfo[block].free.size = wantblocks;
@@ -886,6 +931,8 @@
     }
 
   PROTECT_MALLOC_STATE (1);
+ out:
+  UNLOCK ();
   return result;
 }
 
@@ -996,6 +1043,7 @@
   if (ptr == NULL)
     return;
 
+  LOCK ();
   PROTECT_MALLOC_STATE (0);
 
   for (l = _aligned_blocks; l != NULL; l = l->next)
@@ -1221,6 +1269,7 @@
     }
 
   PROTECT_MALLOC_STATE (1);
+  UNLOCK ();
 }
 
 /* Return memory to the heap.  */
@@ -1384,6 +1433,7 @@
 
   block = BLOCK (ptr);
 
+  LOCK ();
   PROTECT_MALLOC_STATE (0);
 
   type = _heapinfo[block].busy.type;
@@ -1398,7 +1448,7 @@
 	    {
 	      memcpy (result, ptr, size);
 	      _free_internal (ptr);
-	      return result;
+	      goto out;
 	    }
 	}
 
@@ -1451,7 +1501,7 @@
 		  (void) _malloc_internal (blocks * BLOCKSIZE);
 		  _free_internal (previous);
 		}
-	      return NULL;
+	      goto out;
 	    }
 	  if (ptr != result)
 	    memmove (result, ptr, blocks * BLOCKSIZE);
@@ -1471,7 +1521,7 @@
 	     and copy the lesser of the new size and the old. */
 	  result = _malloc_internal (size);
 	  if (result == NULL)
-	    return NULL;
+	    goto out;
 	  memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type));
 	  _free_internal (ptr);
 	}
@@ -1479,6 +1529,8 @@
     }
 
   PROTECT_MALLOC_STATE (1);
+ out:
+  UNLOCK ();
   return result;
 }