summaryrefslogtreecommitdiff
path: root/absl/base/internal/spinlock.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-09-18 15:55:15 -0700
committerGravatar Derek Mauro <dmauro@google.com>2020-09-24 13:47:15 -0400
commitb56cbdd23834a65682c0b46f367f8679e83bc894 (patch)
treedacab9a64dd1a9e9668737e511d1a5420ff96001 /absl/base/internal/spinlock.h
parentb832dce8489ef7b6231384909fd9b68d5a5ff2b7 (diff)
Abseil LTS 2020092320200923
What's New: * `absl::StatusOr<T>` has been released. See our [blog post](https://abseil.io/blog/2020-091021-status) for more information. * Abseil Flags reflection interfaces have been released. * Abseil Flags memory usage has been significantly optimized. * Abseil now supports a "hardened" build mode. This build mode enables runtime checks that guard against programming errors that may lead to security vulnerabilities. Notable Fixes: * Sanitizer dynamic annotations like `AnnotateRWLockCreate` that are also defined by the compiler sanitizer implementation are no longer also defined by Abseil. * Sanitizer macros are now prefixed with `ABSL_` to avoid naming collisions. * Sanitizer usage is now automatically detected and no longer requires macros like `ADDRESS_SANITIZER` to be defined on the command line. Breaking Changes: * Abseil no longer contains a `dynamic_annotations` library. Users using a supported build system (Bazel or CMake) are unaffected by this, but users manually specifying link libraries may get an error about a missing linker input. Baseline: 7680a5f8efe32de4753baadbd63e74e59d95bac1 Cherry picks: None
Diffstat (limited to 'absl/base/internal/spinlock.h')
-rw-r--r--absl/base/internal/spinlock.h44
1 files changed, 19 insertions, 25 deletions
diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h
index 24e2e9a6..e6ac9e64 100644
--- a/absl/base/internal/spinlock.h
+++ b/absl/base/internal/spinlock.h
@@ -36,6 +36,7 @@
#include <atomic>
#include "absl/base/attributes.h"
+#include "absl/base/const_init.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/low_level_scheduling.h"
#include "absl/base/internal/raw_logging.h"
@@ -55,29 +56,22 @@ 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)
+ : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) {}
+
+ // For global SpinLock instances prefer trivial destructor when possible.
+ // Default but non-trivial destructor in some build configurations causes an
+ // extra static initializer.
+#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); }
+#else
+ ~SpinLock() = default;
+#endif
// Acquire this SpinLock.
inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() {
@@ -148,12 +142,13 @@ class ABSL_LOCKABLE SpinLock {
// bit[1] encodes whether a lock uses cooperative scheduling.
// bit[2] encodes whether a lock disables scheduling.
// bit[3:31] encodes time a lock spent on waiting as a 29-bit unsigned int.
- enum { kSpinLockHeld = 1 };
- enum { kSpinLockCooperative = 2 };
- enum { kSpinLockDisabledScheduling = 4 };
- enum { kSpinLockSleeper = 8 };
- enum { kWaitTimeMask = // Includes kSpinLockSleeper.
- ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling) };
+ static constexpr uint32_t kSpinLockHeld = 1;
+ static constexpr uint32_t kSpinLockCooperative = 2;
+ static constexpr uint32_t kSpinLockDisabledScheduling = 4;
+ static constexpr uint32_t kSpinLockSleeper = 8;
+ // Includes kSpinLockSleeper.
+ static constexpr uint32_t kWaitTimeMask =
+ ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling);
// Returns true if the provided scheduling mode is cooperative.
static constexpr bool IsCooperative(
@@ -162,7 +157,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();