about summary refs log tree commit diff
path: root/absl/base/internal
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2019-01-24T15·23-0800
committerXiaoyi Zhang <zhangxy988@gmail.com>2019-01-24T16·10-0500
commit0dffca4e36791c7beeda04da10460b534283948a (patch)
treee2884680d3dfa3fa5b7b4557c900a643dd989b50 /absl/base/internal
parent6b4201f9ef650637510a21b8d6cbcc3bee4a606f (diff)
Export of internal Abseil changes.
--
5804cc13b413412988248835459b90cd15ec43d9 by Abseil Team <absl-team@google.com>:

Mark raw_hash_set::clear() with the ABSL_ATTRIBUTE_REINITIALIZES attribute.

This prevents false positives in the clang-tidy check bugprone-use-after-move;
it allows reset() to be called on a moved-from raw_hash_set without any
warnings, and the raw_hash_set will thereafter be regarded as initialized again.

PiperOrigin-RevId: 230717196

--
ff5961a5600ae19b69a9cba6912126cdf2858f38 by CJ Johnson <johnsoncj@google.com>:

Swaps DisableIfIntegral<> for EnableIfInputIterator<> for Iterator member functions of InlinedVector

PiperOrigin-RevId: 230559521

--
3f9754ccbeecbd40f235c6f2465279e045ff51d9 by Derek Mauro <dmauro@google.com>:

Import GitHub PR 254
https://github.com/abseil/abseil-cpp/pull/254

Fixes warnings from -Wclass-memaccess (base_internal::ThreadIdentity?
with no trivial copy-assignment).

PiperOrigin-RevId: 230536048

--
8af03a654ce9a4a7f55384bc7eb1ed64878ac2ec by Chris Kennelly <ckennelly@google.com>:

absl: cap SpinLock backoff to 4ms

The current backoff logic has 3 problems:
1. It can produce too high values (up to 256ms), which can negatively
affect tail latency. The value was chosen long time ago and now it's
a good idea to reconsider it.
2. It does not have low bound, so on any iteration it can produce
a very small value that will lead to unnecessary cpu consumption.
3. It does not increase low bound with the number of iterations.
So if the SpinLock is actually somehow locked for a very prolonged time,
a waiter can still wake periodically.

Rework the logic to solve these problems.
Add lower bound of 128us, no code should rely on absence of episodic
delays in this range as they can occur everywhere.
Lower upper bound to 4ms. A thread sleeping for 4ms does not consume
significant cpu time (see below).
Grow lower bound with the number of iterations.

This is cpu consumption of a process doing usleep(x) in a loop
(sampled with ps):

    64us -> 4.0%
   128us -> 2.7%
   256us -> 3.5%
   512us -> 2.8%
  1024us -> 1.6%
  2048us -> 0.6%
  4096us -> 0.3%
  8192us -> 0.0%

Few millisecond sleeps do not consume significant time.

PiperOrigin-RevId: 230534015

--
37ebba92289ca556cb2412cd8b3cb4c1ead3def7 by Samuel Benzaquen <sbenza@google.com>:

Add override and dispose hooks to the hashtable sampler.

PiperOrigin-RevId: 230353438

--
89c8f90175233ce9964eb3412df04e8a3cff0c0f by Andy Getzendanner <durandal@google.com>:

Fix a comment typo.

PiperOrigin-RevId: 229986838
GitOrigin-RevId: 5804cc13b413412988248835459b90cd15ec43d9
Change-Id: Iedb5e2cc9c0b924635c1c87b537780ab6b5b899f
Diffstat (limited to 'absl/base/internal')
-rw-r--r--absl/base/internal/spinlock_linux.inc17
-rw-r--r--absl/base/internal/spinlock_wait.cc13
2 files changed, 11 insertions, 19 deletions
diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc
index 94c861dc6ca2..3bbd4954f1ed 100644
--- a/absl/base/internal/spinlock_linux.inc
+++ b/absl/base/internal/spinlock_linux.inc
@@ -51,17 +51,12 @@ extern "C" {
 ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay(
     std::atomic<uint32_t> *w, uint32_t value, int loop,
     absl::base_internal::SchedulingMode) {
-  if (loop != 0) {
-    int save_errno = errno;
-    struct timespec tm;
-    tm.tv_sec = 0;
-    // Increase the delay; we expect (but do not rely on) explicit wakeups.
-    // We don't rely on explicit wakeups because we intentionally allow for
-    // a race on the kSpinLockSleeper bit.
-    tm.tv_nsec = 16 * absl::base_internal::SpinLockSuggestedDelayNS(loop);
-    syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm);
-    errno = save_errno;
-  }
+  int save_errno = errno;
+  struct timespec tm;
+  tm.tv_sec = 0;
+  tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop);
+  syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm);
+  errno = save_errno;
 }
 
 ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic<uint32_t> *w,
diff --git a/absl/base/internal/spinlock_wait.cc b/absl/base/internal/spinlock_wait.cc
index 365a7939494f..7e4f435245a7 100644
--- a/absl/base/internal/spinlock_wait.cc
+++ b/absl/base/internal/spinlock_wait.cc
@@ -65,17 +65,14 @@ int SpinLockSuggestedDelayNS(int loop) {
   r = 0x5deece66dLL * r + 0xb;   // numbers from nrand48()
   delay_rand.store(r, std::memory_order_relaxed);
 
-  r <<= 16;   // 48-bit random number now in top 48-bits.
   if (loop < 0 || loop > 32) {   // limit loop to 0..32
     loop = 32;
   }
-  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
-  // Select top 20..24 bits of lower 48 bits,
-  // giving approximately 0ms to 16ms.
-  // Mean is exponential in loop for first 32 iterations, then 8ms.
-  // The futex path multiplies this by 16, since we expect explicit wakeups
-  // almost always on that path.
-  return static_cast<int>(r >> (44 - (loop >> 3)));
+  const int kMinDelay = 128 << 10;  // 128us
+  // Double delay every 8 iterations, up to 16x (2ms).
+  int delay = kMinDelay << (loop / 8);
+  // Randomize in delay..2*delay range, for resulting 128us..4ms range.
+  return delay | ((delay - 1) & static_cast<int>(r));
 }
 
 }  // namespace base_internal