Merge "Add a couple of new benchmarks."
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 7630d16..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,15 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
-
-Cpp11BracedListStyle: false
-IncludeBlocks: Preserve
\ No newline at end of file
diff --git a/.clang-format b/.clang-format
new file mode 120000
index 0000000..4cefd65
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1 @@
+../system/core/.clang-format-2
\ No newline at end of file
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 7b533a4..11d9fe6 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,2 +1,8 @@
 [Hook Scripts]
 notice = tools/update_notice.sh
+
+[Builtin Hooks]
+clang_format = true
+
+[Builtin Hooks Options]
+clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
diff --git a/libc/kernel/.clang-format b/libc/kernel/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/libc/kernel/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
diff --git a/libc/upstream-freebsd/.clang-format b/libc/upstream-freebsd/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/libc/upstream-freebsd/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
diff --git a/libc/upstream-netbsd/.clang-format b/libc/upstream-netbsd/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/libc/upstream-netbsd/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
diff --git a/libc/upstream-openbsd/.clang-format b/libc/upstream-openbsd/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/libc/upstream-openbsd/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
diff --git a/libm/upstream-freebsd/.clang-format b/libm/upstream-freebsd/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/libm/upstream-freebsd/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
diff --git a/libm/upstream-netbsd/.clang-format b/libm/upstream-netbsd/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/libm/upstream-netbsd/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index ef2f895..6620cdb 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -829,6 +829,63 @@
 #endif
 }
 
+// Jemalloc doesn't pass this test right now, so leave it as disabled.
+TEST(malloc, DISABLED_alloc_after_fork) {
+  // Both of these need to be a power of 2.
+  static constexpr size_t kMinAllocationSize = 8;
+  static constexpr size_t kMaxAllocationSize = 2097152;
+
+  static constexpr size_t kNumAllocatingThreads = 5;
+  static constexpr size_t kNumForkLoops = 100;
+
+  std::atomic_bool stop;
+
+  // Create threads that simply allocate and free different sizes.
+  std::vector<std::thread*> threads;
+  for (size_t i = 0; i < kNumAllocatingThreads; i++) {
+    std::thread* t = new std::thread([&stop] {
+      while (!stop) {
+        for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
+          void* ptr = malloc(size);
+          if (ptr == nullptr) {
+            return;
+          }
+          // Make sure this value is not optimized away.
+          asm volatile("" : : "r,m"(ptr) : "memory");
+          free(ptr);
+        }
+      }
+    });
+    threads.push_back(t);
+  }
+
+  // Create a thread to fork and allocate.
+  for (size_t i = 0; i < kNumForkLoops; i++) {
+    pid_t pid;
+    if ((pid = fork()) == 0) {
+      for (size_t size = kMinAllocationSize; size <= kMaxAllocationSize; size <<= 1) {
+        void* ptr = malloc(size);
+        ASSERT_TRUE(ptr != nullptr);
+        // Make sure this value is not optimized away.
+        asm volatile("" : : "r,m"(ptr) : "memory");
+        // Make sure we can touch all of the allocation.
+        memset(ptr, 0x1, size);
+        ASSERT_LE(size, malloc_usable_size(ptr));
+        free(ptr);
+      }
+      _exit(10);
+    }
+    ASSERT_NE(-1, pid);
+    AssertChildExited(pid, 10);
+  }
+
+  stop = true;
+  for (auto thread : threads) {
+    thread->join();
+    delete thread;
+  }
+}
+
 TEST(android_mallopt, error_on_unexpected_option) {
 #if defined(__BIONIC__)
   const int unrecognized_option = -1;