From 5bf048b8425cc0a342e4647932de19e25ffd6ad7 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 26 Oct 2020 09:50:44 -0700 Subject: Export of internal Abseil changes -- 730bb88bee556aa11fa19aa33e1434cb6fa78985 by Evan Brown : Support missing allocator-related constructors in b-tree. See [reference](https://en.cppreference.com/w/cpp/container/set/set). Also use allocator_traits::select_on_container_copy_construction() to get allocator for copy construction. PiperOrigin-RevId: 339058322 -- b6cc121689ae3e452d1db2d66122cb198d25142b by Derek Mauro : Fix more sign-compare warnings PiperOrigin-RevId: 339057920 -- 0e2c62da1dcaf6529abab952bdcc96c6de2d9506 by Abseil Team : Add missing include PiperOrigin-RevId: 339054753 -- d5a9ec2d1e40fe6359e720942e4955009ee415ec by Derek Mauro : Stop disabling sign-compare warnings for non-test targets. Our users complain about these. This does not catch issues in header-only libraries (like btree.h) but we may work on those in the future PiperOrigin-RevId: 338967089 -- 0c062c542a4c61ea0f65d25811827c0858e3adde by Abseil Team : Improve cache-locality for ThreadIdentity and PerThreadSynch. This is a change based on an observation in RPC benchmarks that shows significant cycles being spent in waking up a thread, 99.8% of which was on cache misses. Investigating this a bit more, it turns out to be due to sharing the cache line with the waiter state. To fix this issue, the following changes are introduced: - Reorder fields in PerThreadSync so that it fits in a single cache line The size of this structure was 80 bytes before this change. Note: Manually inspected all booleans to make sure they are not modified by multiple threads concurrently. PiperOrigin-RevId: 338852058 -- a90d6f2b2346385017e32dd8ae1b5ca691a5863f by Derek Mauro : Delete GCC 4.9 test script. It is no longer supported PiperOrigin-RevId: 338779452 -- 7274008d4757e88869110be9db39d03d911ae2b5 by Abseil Team : Fix the usage example in which SetFlag should take a pointer. PiperOrigin-RevId: 338744529 GitOrigin-RevId: 730bb88bee556aa11fa19aa33e1434cb6fa78985 Change-Id: Iff99594c4022e60e482a392d334b376c7ae8883e --- absl/base/internal/thread_identity.h | 79 ++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'absl/base') diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index ceb109b4..c61d1feb 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -32,6 +32,7 @@ #include "absl/base/config.h" #include "absl/base/internal/per_thread_tls.h" +#include "absl/base/optimization.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -69,30 +70,28 @@ struct PerThreadSynch { // is using this PerThreadSynch as a terminator. Its // skip field must not be filled in because the loop // might then skip over the terminator. - - // The wait parameters of the current wait. waitp is null if the - // thread is not waiting. Transitions from null to non-null must - // occur before the enqueue commit point (state = kQueued in - // Enqueue() and CondVarEnqueue()). Transitions from non-null to - // null must occur after the wait is finished (state = kAvailable in - // Mutex::Block() and CondVar::WaitCommon()). This field may be - // changed only by the thread that describes this PerThreadSynch. A - // special case is Fer(), which calls Enqueue() on another thread, - // but with an identical SynchWaitParams pointer, thus leaving the - // pointer unchanged. - SynchWaitParams *waitp; - - bool suppress_fatal_errors; // If true, try to proceed even in the face of - // broken invariants. This is used within fatal - // signal handlers to improve the chances of - // debug logging information being output - // successfully. - - intptr_t readers; // Number of readers in mutex. - int priority; // Priority of thread (updated every so often). - - // When priority will next be read (cycles). - int64_t next_priority_read_cycles; + bool wake; // This thread is to be woken from a Mutex. + // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the + // waiter is waiting on the mutex as part of a CV Wait or Mutex Await. + // + // The value of "x->cond_waiter" is meaningless if "x" is not on a + // Mutex waiter list. + bool cond_waiter; + bool maybe_unlocking; // Valid at head of Mutex waiter queue; + // true if UnlockSlow could be searching + // for a waiter to wake. Used for an optimization + // in Enqueue(). true is always a valid value. + // Can be reset to false when the unlocker or any + // writer releases the lock, or a reader fully + // releases the lock. It may not be set to false + // by a reader that decrements the count to + // non-zero. protected by mutex spinlock + bool suppress_fatal_errors; // If true, try to proceed even in the face + // of broken invariants. This is used within + // fatal signal handlers to improve the + // chances of debug logging information being + // output successfully. + int priority; // Priority of thread (updated every so often). // State values: // kAvailable: This PerThreadSynch is available. @@ -111,30 +110,30 @@ struct PerThreadSynch { }; std::atomic state; - bool maybe_unlocking; // Valid at head of Mutex waiter queue; - // true if UnlockSlow could be searching - // for a waiter to wake. Used for an optimization - // in Enqueue(). true is always a valid value. - // Can be reset to false when the unlocker or any - // writer releases the lock, or a reader fully releases - // the lock. It may not be set to false by a reader - // that decrements the count to non-zero. - // protected by mutex spinlock + // The wait parameters of the current wait. waitp is null if the + // thread is not waiting. Transitions from null to non-null must + // occur before the enqueue commit point (state = kQueued in + // Enqueue() and CondVarEnqueue()). Transitions from non-null to + // null must occur after the wait is finished (state = kAvailable in + // Mutex::Block() and CondVar::WaitCommon()). This field may be + // changed only by the thread that describes this PerThreadSynch. A + // special case is Fer(), which calls Enqueue() on another thread, + // but with an identical SynchWaitParams pointer, thus leaving the + // pointer unchanged. + SynchWaitParams* waitp; - bool wake; // This thread is to be woken from a Mutex. + intptr_t readers; // Number of readers in mutex. - // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the - // waiter is waiting on the mutex as part of a CV Wait or Mutex Await. - // - // The value of "x->cond_waiter" is meaningless if "x" is not on a - // Mutex waiter list. - bool cond_waiter; + // When priority will next be read (cycles). + int64_t next_priority_read_cycles; // Locks held; used during deadlock detection. // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity(). SynchLocksHeld *all_locks; }; +// The instances of this class are allocated in NewThreadIdentity() with an +// alignment of PerThreadSynch::kAlignment. struct ThreadIdentity { // Must be the first member. The Mutex implementation requires that // the PerThreadSynch object associated with each thread is -- cgit v1.2.3