Move `absl::MutexLock sample_lock` out of the global graveyard critical section.

PiperOrigin-RevId: 985714023
Change-Id: I78d9ab07ff4109683d1db28a28db8e615a374e68
diff --git a/absl/profiling/internal/sample_recorder.h b/absl/profiling/internal/sample_recorder.h
index 0d14027..8663d6c 100644
--- a/absl/profiling/internal/sample_recorder.h
+++ b/absl/profiling/internal/sample_recorder.h
@@ -169,23 +169,29 @@
 template <typename T>
 template <typename... Targs>
 T* SampleRecorder<T>::PopDead(Targs... args) {
-  absl::ReleasableMutexLock graveyard_lock(graveyard_.init_mu);
+  T* sample;
+  {
+    absl::MutexLock graveyard_lock(graveyard_.init_mu);
 
-  // The list is circular, so eventually it collapses down to
-  //   graveyard_.dead == &graveyard_
-  // when it is empty.
-  T* sample = graveyard_.dead;
-  if (sample == &graveyard_) return nullptr;
+    // The list is circular, so eventually it collapses down to
+    //   graveyard_.dead == &graveyard_
+    // when it is empty.
+    sample = graveyard_.dead;
+    if (sample == &graveyard_) return nullptr;
 
+    graveyard_.dead = ABSL_TS_UNCHECKED_READ(sample->dead);
+    // Release the global graveyard lock early, before the potentially slow
+    // preparation.
+  }
+  // `sample` is detached from the graveyard and will not be used in PopDead.
+  // SampleRecorder<T>::Iterate will acquire per sample lock, so there will be
+  // no data race either.
   absl::MutexLock sample_lock(sample->init_mu);
-  graveyard_.dead = sample->dead;
-  // Release the global graveyard lock early, before the potentially slow
-  // preparation.
-  graveyard_lock.Release();
-  // Prepare the sample while still holding the per-sample lock.
-  // `Iterate` will wait for the lock to be released.
-  sample->dead = nullptr;
+  // Note: consider PrepareForSampling out of the lock.
+  // Currently many clients have PrepareForSampling marked as
+  // ABSL_EXCLUSIVE_LOCKS_REQUIRED.
   sample->PrepareForSampling(std::forward<Targs>(args)...);
+  sample->dead = nullptr;
   return sample;
 }