+2007-08-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * emacs.c (main)
+ [HAVE_GTK_AND_PTHREAD && !SYSTEM_MALLOC && !DOUG_LEA_MALLOC]:
+ Call malloc_enable_thread on interactive startup.
+
+ * gmalloc.c (_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.
+
2007-08-06 Chong Yidong <cyd@stupidchicken.com>
* xdisp.c (redisplay_window): When restoring original buffer
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
#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()
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
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)