Bug 680190 - Notify jemalloc when forking on Android; r=cjones
authorJim Chen <jimnchen@gmail.com>
Tue, 30 Aug 2011 17:11:36 -0700
changeset 76245 157511556e27b5a1042ffe87187bdfa4fc88e4cd
parent 76244 902d3de6f41dfb75d8896ef3e9c86b46ba9ea771
child 76246 a2b9d2cfc61a41908a58d4c8cabececf3d99a933
push id21087
push usermak77@bonardo.net
push dateWed, 31 Aug 2011 08:44:58 +0000
treeherdermozilla-central@c7e6f57e1732 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs680190
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 680190 - Notify jemalloc when forking on Android; r=cjones
ipc/chromium/src/base/process_util_linux.cc
memory/jemalloc/jemalloc.c
--- a/ipc/chromium/src/base/process_util_linux.cc
+++ b/ipc/chromium/src/base/process_util_linux.cc
@@ -14,16 +14,23 @@
 
 #include "base/debug_util.h"
 #include "base/eintr_wrapper.h"
 #include "base/file_util.h"
 #include "base/logging.h"
 #include "base/string_tokenizer.h"
 #include "base/string_util.h"
 
+#ifdef MOZ_MEMORY_ANDROID
+extern "C" {
+extern void _malloc_prefork(void);
+extern void _malloc_postfork(void);
+}
+#endif
+
 namespace {
 
 enum ParsingState {
   KEY_NAME,
   KEY_VALUE
 };
 
 static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
@@ -39,17 +46,27 @@ bool LaunchApp(const std::vector<std::st
                    wait, process_handle);
 }
 
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                const environment_map& env_vars_to_set,
                bool wait, ProcessHandle* process_handle,
                ProcessArchitecture arch) {
+#ifdef MOZ_MEMORY_ANDROID
+  /* We specifically don't call pthread_atfork in jemalloc because it is not
+    available in bionic until 2.3. However without it, jemalloc could
+    potentially deadlock, when stl allocates memory through jemalloc, after
+    fork and before execvp. Therefore, we must manually inform jemalloc here */
+  ::_malloc_prefork();
+#endif
   pid_t pid = fork();
+#ifdef MOZ_MEMORY_ANDROID
+  ::_malloc_postfork();
+#endif
   if (pid < 0)
     return false;
 
   if (pid == 0) {
     InjectiveMultimap fd_shuffle;
     for (file_handle_mapping_vector::const_iterator
         it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) {
       fd_shuffle.push_back(InjectionArc(it->first, it->second, false));
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -1261,18 +1261,23 @@ static void	*huge_palloc(size_t alignmen
 static void	*huge_ralloc(void *ptr, size_t size, size_t oldsize);
 static void	huge_dalloc(void *ptr);
 static void	malloc_print_stats(void);
 #ifndef MOZ_MEMORY_WINDOWS
 static
 #endif
 bool		malloc_init_hard(void);
 
+#ifdef MOZ_MEMORY_ANDROID
+void	_malloc_prefork(void);
+void	_malloc_postfork(void);
+#else
 static void	_malloc_prefork(void);
 static void	_malloc_postfork(void);
+#endif
 
 #ifdef MOZ_MEMORY_DARWIN
 /*
  * MALLOC_ZONE_T_NOTE
  *
  * On Darwin, we hook into the memory allocator using a malloc_zone_t struct.
  * We must be very careful around this struct because of different behaviour on
  * different versions of OSX.
@@ -5601,16 +5606,18 @@ MALLOC_OUT:
 #ifndef MOZ_MEMORY_WINDOWS
 		/* Print statistics at exit. */
 		atexit(malloc_print_stats);
 #endif
 	}
 
 #if (!defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_MEMORY_ANDROID))
 	/* Prevent potential deadlock on malloc locks after fork. */
+	/* XXX on Android there is no pthread_atfork, so we specifically
+	   call _malloc_prefork and _malloc_postfork in process_util_linux.cc */
 	pthread_atfork(_malloc_prefork, _malloc_postfork, _malloc_postfork);
 #endif
 
 	/* Set variables according to the value of opt_small_max_2pow. */
 	if (opt_small_max_2pow < opt_quantum_2pow)
 		opt_small_max_2pow = opt_quantum_2pow;
 	small_max = (1U << opt_small_max_2pow);
 
@@ -6431,17 +6438,21 @@ size_t
 /******************************************************************************/
 /*
  * Begin library-private functions, used by threading libraries for protection
  * of malloc during fork().  These functions are only called if the program is
  * running in threaded mode, so there is no need to check whether the program
  * is threaded here.
  */
 
+#ifdef MOZ_MEMORY_ANDROID
+void
+#else
 static void
+#endif
 _malloc_prefork(void)
 {
 	unsigned i;
 
 	/* Acquire all mutexes in a safe order. */
 
 	malloc_spin_lock(&arenas_lock);
 	for (i = 0; i < narenas; i++) {
@@ -6449,17 +6460,21 @@ static void
 			malloc_spin_lock(&arenas[i]->lock);
 	}
 
 	malloc_mutex_lock(&base_mtx);
 
 	malloc_mutex_lock(&huge_mtx);
 }
 
+#ifdef MOZ_MEMORY_ANDROID
+void
+#else
 static void
+#endif
 _malloc_postfork(void)
 {
 	unsigned i;
 
 	/* Release all mutexes, now that fork() has completed. */
 
 	malloc_mutex_unlock(&huge_mtx);