tcmalloc: Fix thread-safety (annotalysis) annotations

Chromium's fork of gperftools/tcmalloc contains some thread-safety
annotations; however those annotations have not been exercised for
some time, as they used macros/attributes only supported by a
legacy branch of gcc.

crrev.com/c/2702729 converted those macros to support modern
versions of clang; this CR fixes the annotations that were enabled.
For the most part, this just requires re-enabling annotations on
member functions that take/release locks. For the tcmalloc fork
(pre-fork and post-fork) handlers, we mark the functions as
exempt from this analysis, as it takes a dynamic number of locks.

Tested:
* Manually enabled "-Wthread-safety" for host tool, built base/allocator

Change-Id: I66aeff3c7d3c251ffb0400fcf4bc79ce8e222c6e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2702605
Reviewed-by: Primiano Tucci <primiano@chromium.org>
Commit-Queue: Venkatesh Srinivas <venkateshs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#856342}
GitOrigin-RevId: fe744a3cae1af8e14f7e42044921def8514481e9
diff --git a/src/base/low_level_alloc.cc b/src/base/low_level_alloc.cc
index 6b467cf..6a944b6 100644
--- a/src/base/low_level_alloc.cc
+++ b/src/base/low_level_alloc.cc
@@ -249,7 +249,7 @@
       this->arena_->mu.Lock();
     }
     ~ArenaLock() { RAW_CHECK(this->left_, "haven't left Arena region"); }
-    void Leave() /*UNLOCK_FUNCTION()*/ {
+    void Leave() UNLOCK_FUNCTION() {
       this->arena_->mu.Unlock();
 #if 0
       if (this->mask_valid_) {
diff --git a/src/base/spinlock.h b/src/base/spinlock.h
index 7243aea..9b5a7f6 100644
--- a/src/base/spinlock.h
+++ b/src/base/spinlock.h
@@ -63,9 +63,7 @@
   }
 
   // Acquire this SpinLock.
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline void Lock() /*EXCLUSIVE_LOCK_FUNCTION()*/ {
+  inline void Lock() EXCLUSIVE_LOCK_FUNCTION() {
     if (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,
                                              kSpinLockHeld) != kSpinLockFree) {
       SlowLock();
@@ -88,9 +86,7 @@
   }
 
   // Release this SpinLock, which must be held by the calling thread.
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline void Unlock() /*UNLOCK_FUNCTION()*/ {
+  inline void Unlock() UNLOCK_FUNCTION() {
     ANNOTATE_RWLOCK_RELEASED(this, 1);
     uint64 prev_value = static_cast<uint64>(
         base::subtle::Release_AtomicExchange(&lockword_, kSpinLockFree));
@@ -132,9 +128,7 @@
       : lock_(l) {
     l->Lock();
   }
-  // TODO(csilvers): uncomment the annotation when we figure out how to
-  //                 support this macro with 0 args (see thread_annotations.h)
-  inline ~SpinLockHolder() /*UNLOCK_FUNCTION()*/ { lock_->Unlock(); }
+  inline ~SpinLockHolder() UNLOCK_FUNCTION() { lock_->Unlock(); }
 };
 // Catch bug where variable name is omitted, e.g. SpinLockHolder (&lock);
 #define SpinLockHolder(x) COMPILE_ASSERT(0, spin_lock_decl_missing_var_name)
diff --git a/src/central_freelist.h b/src/central_freelist.h
index 4148680..0f66e0c 100644
--- a/src/central_freelist.h
+++ b/src/central_freelist.h
@@ -82,11 +82,11 @@
 
   // Lock/Unlock the internal SpinLock. Used on the pthread_atfork call
   // to set the lock in a consistent state before the fork.
-  void Lock() {
+  void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_) {
     lock_.Lock();
   }
 
-  void Unlock() {
+  void Unlock() UNLOCK_FUNCTION(lock_) {
     lock_.Unlock();
   }
 
diff --git a/src/static_vars.cc b/src/static_vars.cc
index da68094..73beb15 100644
--- a/src/static_vars.cc
+++ b/src/static_vars.cc
@@ -52,14 +52,14 @@
 // sure the central_cache locks remain in a consisten state in the forked
 // version of the thread.
 
-void CentralCacheLockAll()
+void CentralCacheLockAll() NO_THREAD_SAFETY_ANALYSIS
 {
   Static::pageheap_lock()->Lock();
   for (int i = 0; i < Static::num_size_classes(); ++i)
     Static::central_cache()[i].Lock();
 }
 
-void CentralCacheUnlockAll()
+void CentralCacheUnlockAll() NO_THREAD_SAFETY_ANALYSIS
 {
   for (int i = 0; i < Static::num_size_classes(); ++i)
     Static::central_cache()[i].Unlock();