about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--absl/base/internal/spinlock.cc37
-rw-r--r--absl/base/internal/spinlock.h19
-rw-r--r--absl/base/macros.h30
-rw-r--r--absl/flags/flag.h1
-rw-r--r--absl/hash/hash_test.cc2
-rw-r--r--absl/synchronization/internal/mutex_nonprod.inc20
6 files changed, 14 insertions, 95 deletions
diff --git a/absl/base/internal/spinlock.cc b/absl/base/internal/spinlock.cc
index 7cac72f97f28..a7d44f3eb091 100644
--- a/absl/base/internal/spinlock.cc
+++ b/absl/base/internal/spinlock.cc
@@ -79,29 +79,6 @@ SpinLock::SpinLock(base_internal::SchedulingMode mode)
   ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
 }
 
-SpinLock::SpinLock(base_internal::LinkerInitialized,
-                   base_internal::SchedulingMode mode) {
-  ABSL_TSAN_MUTEX_CREATE(this, 0);
-  if (IsCooperative(mode)) {
-    InitLinkerInitializedAndCooperative();
-  }
-  // Otherwise, lockword_ is already initialized.
-}
-
-// Static (linker initialized) spinlocks always start life as functional
-// non-cooperative locks.  When their static constructor does run, it will call
-// this initializer to augment the lockword with the cooperative bit.  By
-// actually taking the lock when we do this we avoid the need for an atomic
-// operation in the regular unlock path.
-//
-// SlowLock() must be careful to re-test for this bit so that any outstanding
-// waiters may be upgraded to cooperative status.
-void SpinLock::InitLinkerInitializedAndCooperative() {
-  Lock();
-  lockword_.fetch_or(kSpinLockCooperative, std::memory_order_relaxed);
-  Unlock();
-}
-
 // Monitor the lock to see if its value changes within some time period
 // (adaptive_spin_count loop iterations). The last value read from the lock
 // is returned from the method.
@@ -128,6 +105,14 @@ void SpinLock::SlowLock() {
   if ((lock_value & kSpinLockHeld) == 0) {
     return;
   }
+
+  base_internal::SchedulingMode scheduling_mode;
+  if ((lock_value & kSpinLockCooperative) != 0) {
+    scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL;
+  } else {
+    scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY;
+  }
+
   // The lock was not obtained initially, so this thread needs to wait for
   // it.  Record the current timestamp in the local variable wait_start_time
   // so the total wait time can be stored in the lockword once this thread
@@ -158,12 +143,6 @@ void SpinLock::SlowLock() {
       }
     }
 
-    base_internal::SchedulingMode scheduling_mode;
-    if ((lock_value & kSpinLockCooperative) != 0) {
-      scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL;
-    } else {
-      scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY;
-    }
     // SpinLockDelay() calls into fiber scheduler, we need to see
     // synchronization there to avoid false positives.
     ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0);
diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h
index 2b08a2d6e2f1..2222398b16b4 100644
--- a/absl/base/internal/spinlock.h
+++ b/absl/base/internal/spinlock.h
@@ -56,27 +56,9 @@ class ABSL_LOCKABLE SpinLock {
     ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
   }
 
-  // Special constructor for use with static SpinLock objects.  E.g.,
-  //
-  //    static SpinLock lock(base_internal::kLinkerInitialized);
-  //
-  // When initialized using this constructor, we depend on the fact
-  // that the linker has already initialized the memory appropriately. The lock
-  // is initialized in non-cooperative mode.
-  //
-  // A SpinLock constructed like this can be freely used from global
-  // initializers without worrying about the order in which global
-  // initializers run.
-  explicit SpinLock(base_internal::LinkerInitialized) {
-    // Does nothing; lockword_ is already initialized
-    ABSL_TSAN_MUTEX_CREATE(this, 0);
-  }
-
   // Constructors that allow non-cooperative spinlocks to be created for use
   // inside thread schedulers.  Normal clients should not use these.
   explicit SpinLock(base_internal::SchedulingMode mode);
-  SpinLock(base_internal::LinkerInitialized,
-           base_internal::SchedulingMode mode);
 
   // Constructor for global SpinLock instances.  See absl/base/const_init.h.
   constexpr SpinLock(absl::ConstInitType, base_internal::SchedulingMode mode)
@@ -168,7 +150,6 @@ class ABSL_LOCKABLE SpinLock {
   }
 
   uint32_t TryLockInternal(uint32_t lock_value, uint32_t wait_cycles);
-  void InitLinkerInitializedAndCooperative();
   void SlowLock() ABSL_ATTRIBUTE_COLD;
   void SlowUnlock(uint32_t lock_value) ABSL_ATTRIBUTE_COLD;
   uint32_t SpinLoop();
diff --git a/absl/base/macros.h b/absl/base/macros.h
index 2c4e3570cd55..ea1da65ba272 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -55,36 +55,6 @@ auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
 ABSL_NAMESPACE_END
 }  // namespace absl
 
-// kLinkerInitialized
-//
-// An enum used only as a constructor argument to indicate that a variable has
-// static storage duration, and that the constructor should do nothing to its
-// state. Use of this macro indicates to the reader that it is legal to
-// declare a static instance of the class, provided the constructor is given
-// the absl::base_internal::kLinkerInitialized argument.
-//
-// Normally, it is unsafe to declare a static variable that has a constructor or
-// a destructor because invocation order is undefined. However, if the type can
-// be zero-initialized (which the loader does for static variables) into a valid
-// state and the type's destructor does not affect storage, then a constructor
-// for static initialization can be declared.
-//
-// Example:
-//       // Declaration
-//       explicit MyClass(absl::base_internal:LinkerInitialized x) {}
-//
-//       // Invocation
-//       static MyClass my_global(absl::base_internal::kLinkerInitialized);
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-namespace base_internal {
-enum LinkerInitialized {
-  kLinkerInitialized = 0,
-};
-}  // namespace base_internal
-ABSL_NAMESPACE_END
-}  // namespace absl
-
 // ABSL_FALLTHROUGH_INTENDED
 //
 // Annotates implicit fall-through between switch labels, allowing a case to
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index 8dd1b9be7af8..ca7d581fce71 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -41,6 +41,7 @@
 #include "absl/flags/internal/flag.h"
 #include "absl/flags/internal/registry.h"
 #include "absl/flags/marshalling.h"
+#include "absl/strings/string_view.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index 5e6a8b188b40..b38d46d47dd3 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -407,7 +407,7 @@ using IntSequenceTypes =
 INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueSequenceTest, IntSequenceTypes);
 
 // Private type that only supports AbslHashValue to make sure our chosen hash
-// implentation is recursive within absl::Hash.
+// implementation is recursive within absl::Hash.
 // It uses std::abs() on the value to provide different bitwise representations
 // of the same logical value.
 struct Private {
diff --git a/absl/synchronization/internal/mutex_nonprod.inc b/absl/synchronization/internal/mutex_nonprod.inc
index a1502e727da4..d83bc8a94c75 100644
--- a/absl/synchronization/internal/mutex_nonprod.inc
+++ b/absl/synchronization/internal/mutex_nonprod.inc
@@ -209,31 +209,22 @@ class SynchronizationStorage {
   // Instances allocated on the heap or on the stack should use the default
   // constructor.
   SynchronizationStorage()
-      : is_dynamic_(true), once_() {}
-
-  // Instances allocated in static storage (not on the heap, not on the
-  // stack) should use this constructor.
-  explicit SynchronizationStorage(base_internal::LinkerInitialized) {}
+      : destruct_(true), once_() {}
 
   constexpr explicit SynchronizationStorage(absl::ConstInitType)
-      : is_dynamic_(false), once_(), space_{{0}} {}
+      : destruct_(false), once_(), space_{{0}} {}
 
   SynchronizationStorage(SynchronizationStorage&) = delete;
   SynchronizationStorage& operator=(SynchronizationStorage&) = delete;
 
   ~SynchronizationStorage() {
-    if (is_dynamic_) {
+    if (destruct_) {
       get()->~T();
     }
   }
 
   // Retrieve the object in storage. This is fast and thread safe, but does
   // incur the cost of absl::call_once().
-  //
-  // For instances in static storage constructed with the
-  // LinkerInitialized constructor, may be called at any time without
-  // regard for order of dynamic initialization or destruction of objects
-  // in static storage. See the class comment for caveats.
   T* get() {
     absl::call_once(once_, SynchronizationStorage::Construct, this);
     return reinterpret_cast<T*>(&space_);
@@ -245,10 +236,7 @@ class SynchronizationStorage {
   }
 
   // When true, T's destructor is run when this is destructed.
-  //
-  // The LinkerInitialized constructor assumes this value will be set
-  // false by static initialization.
-  bool is_dynamic_;
+  const bool destruct_;
 
   absl::once_flag once_;