Skip to content

Commit ed0efc0

Browse files
conNULLcopybara-github
authored andcommitted
Change Abseil's SpinLock adaptive_spin_count to a class static variable that can be set by tcmalloc friend classes.
PiperOrigin-RevId: 826226544 Change-Id: I8f8cb5ce199eab9ca63fcd475b536f4a1f512a19
1 parent f43bcc0 commit ed0efc0

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

absl/base/internal/spinlock.cc

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,23 @@ void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock,
7171
}
7272

7373
// Monitor the lock to see if its value changes within some time period
74-
// (adaptive_spin_count loop iterations). The last value read from the lock
74+
// (adaptive_spin_count_ loop iterations). The last value read from the lock
7575
// is returned from the method.
76+
ABSL_CONST_INIT std::atomic<int> SpinLock::adaptive_spin_count_{0};
7677
uint32_t SpinLock::SpinLoop() {
7778
// We are already in the slow path of SpinLock, initialize the
7879
// adaptive_spin_count here.
79-
ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count;
80-
ABSL_CONST_INIT static int adaptive_spin_count = 0;
81-
LowLevelCallOnce(&init_adaptive_spin_count,
82-
[]() { adaptive_spin_count = NumCPUs() > 1 ? 1000 : 1; });
83-
84-
int c = adaptive_spin_count;
80+
if (adaptive_spin_count_.load(std::memory_order_relaxed) == 0) {
81+
int current_spin_count = 0;
82+
int new_spin_count = NumCPUs() > 1 ? 1000 : 1;
83+
// If this fails, the value will remain unchanged. We may not spin for the
84+
// intended duration, but that is still safe. We will try again on the next
85+
// call to SpinLoop.
86+
adaptive_spin_count_.compare_exchange_weak(
87+
current_spin_count, new_spin_count, std::memory_order_relaxed,
88+
std::memory_order_relaxed);
89+
}
90+
int c = adaptive_spin_count_.load(std::memory_order_relaxed);
8591
uint32_t lock_value;
8692
do {
8793
lock_value = lockword_.load(std::memory_order_relaxed);

absl/base/internal/spinlock.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace tcmalloc {
4747
namespace tcmalloc_internal {
4848

4949
class AllocationGuardSpinLockHolder;
50+
class Static;
5051

5152
} // namespace tcmalloc_internal
5253
} // namespace tcmalloc
@@ -173,6 +174,16 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED SpinLock {
173174
// Provide access to protected method above. Use for testing only.
174175
friend struct SpinLockTest;
175176
friend class tcmalloc::tcmalloc_internal::AllocationGuardSpinLockHolder;
177+
friend class tcmalloc::tcmalloc_internal::Static;
178+
179+
static int GetAdaptiveSpinCount() {
180+
return adaptive_spin_count_.load(std::memory_order_relaxed);
181+
}
182+
static void SetAdaptiveSpinCount(int count) {
183+
adaptive_spin_count_.store(count, std::memory_order_relaxed);
184+
}
185+
186+
static std::atomic<int> adaptive_spin_count_;
176187

177188
private:
178189
// lockword_ is used to store the following:

0 commit comments

Comments
 (0)