diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h index d0e1649..d535093 100644 --- a/absl/base/internal/spinlock.h +++ b/absl/base/internal/spinlock.h
@@ -31,6 +31,7 @@ #include <atomic> #include <cstdint> +#include <mutex> #include <type_traits> #include "absl/base/attributes.h" @@ -247,25 +248,18 @@ // Corresponding locker object that arranges to acquire a spinlock for // the duration of a C++ scope. -class ABSL_SCOPED_LOCKABLE [[nodiscard]] SpinLockHolder { +class ABSL_SCOPED_LOCKABLE [[nodiscard]] SpinLockHolder + : public std::lock_guard<SpinLock> { public: inline explicit SpinLockHolder( SpinLock& l ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)) ABSL_EXCLUSIVE_LOCK_FUNCTION(l) - : lock_(l) { - l.lock(); - } + : std::lock_guard<SpinLock>(l) {} ABSL_DEPRECATE_AND_INLINE() inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l) : SpinLockHolder(*l) {} - inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() { lock_.unlock(); } - - SpinLockHolder(const SpinLockHolder&) = delete; - SpinLockHolder& operator=(const SpinLockHolder&) = delete; - - private: - SpinLock& lock_; + inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() = default; }; // Register a hook for profiling support.
diff --git a/absl/base/internal/strerror_test.cc b/absl/base/internal/strerror_test.cc index e32d5b5..d12c537 100644 --- a/absl/base/internal/strerror_test.cc +++ b/absl/base/internal/strerror_test.cc
@@ -39,7 +39,8 @@ TEST(StrErrorTest, InvalidErrorCode) { errno = ERANGE; EXPECT_THAT(absl::base_internal::StrError(-1), - AnyOf(Eq("No error information"), Eq("Unknown error -1"))); + AnyOf(Eq("No error information"), Eq("Unknown error -1"), + Eq("Unknown error"))); EXPECT_THAT(errno, Eq(ERANGE)); }
diff --git a/absl/debugging/internal/borrowed_fixup_buffer.cc b/absl/debugging/internal/borrowed_fixup_buffer.cc index dae78a7..507a0a2 100644 --- a/absl/debugging/internal/borrowed_fixup_buffer.cc +++ b/absl/debugging/internal/borrowed_fixup_buffer.cc
@@ -21,6 +21,7 @@ #include <atomic> #include <iterator> +#include <utility> #include "absl/base/attributes.h" #include "absl/base/config.h" @@ -46,28 +47,27 @@ BorrowedFixupBuffer::~BorrowedFixupBuffer() { if (borrowed_) { - Unlock(); + std::move(*this).Unlock(); } else { base_internal::LowLevelAlloc::Free(frames_); } } -BorrowedFixupBuffer::BorrowedFixupBuffer(size_t length) { - FixupStackBuffer* fixup_buffer = - 0 < length && length <= FixupStackBuffer::kMaxStackElements ? TryLock() - : nullptr; - borrowed_ = fixup_buffer != nullptr; +BorrowedFixupBuffer::BorrowedFixupBuffer(size_t length) + : borrowed_(0 < length && length <= FixupStackBuffer::kMaxStackElements + ? TryLock() + : nullptr) { if (borrowed_) { - InitViaBorrow(fixup_buffer); + InitViaBorrow(); } else { InitViaAllocation(length); } } -void BorrowedFixupBuffer::InitViaBorrow(FixupStackBuffer* borrowed_buffer) { +void BorrowedFixupBuffer::InitViaBorrow() { assert(borrowed_); - frames_ = borrowed_buffer->frames; - sizes_ = borrowed_buffer->sizes; + frames_ = borrowed_->frames; + sizes_ = borrowed_->sizes; } void BorrowedFixupBuffer::InitViaAllocation(size_t length) { @@ -92,25 +92,25 @@ length * sizeof(*frames_))) int[length]; } -BorrowedFixupBuffer::FixupStackBuffer* BorrowedFixupBuffer::Find() { - size_t i = absl::Hash<const void*>()(this) % - std::size(FixupStackBuffer::g_instances); - return &FixupStackBuffer::g_instances[i]; -} - [[nodiscard]] BorrowedFixupBuffer::FixupStackBuffer* BorrowedFixupBuffer::TryLock() { - FixupStackBuffer* instance = Find(); - // Use memory_order_acquire to ensure that no reads and writes on the borrowed - // buffer are reordered before the borrowing. - return !instance->in_use.test_and_set(std::memory_order_acquire) ? instance - : nullptr; + constexpr size_t kNumSlots = std::size(FixupStackBuffer::g_instances); + const size_t i = absl::Hash<const void*>()(this) % kNumSlots; + for (size_t k = 0; k < kNumSlots; ++k) { + auto* instance = &FixupStackBuffer::g_instances[(i + k) % kNumSlots]; + // Use memory_order_acquire to ensure that no reads and writes on the + // borrowed buffer are reordered before the borrowing. + if (!instance->in_use.test_and_set(std::memory_order_acquire)) { + return instance; + } + } + return nullptr; } -void BorrowedFixupBuffer::Unlock() { +void BorrowedFixupBuffer::Unlock() && { // Use memory_order_release to ensure that no reads and writes on the borrowed // buffer are reordered after the borrowing. - Find()->in_use.clear(std::memory_order_release); + borrowed_->in_use.clear(std::memory_order_release); } } // namespace internal_stacktrace
diff --git a/absl/debugging/internal/borrowed_fixup_buffer.h b/absl/debugging/internal/borrowed_fixup_buffer.h index c5ea7a3..a8f00c8 100644 --- a/absl/debugging/internal/borrowed_fixup_buffer.h +++ b/absl/debugging/internal/borrowed_fixup_buffer.h
@@ -42,26 +42,23 @@ int* sizes() const { return sizes_; } private: + struct FixupStackBuffer; + uintptr_t* frames_; int* sizes_; - // Have we borrowed a pre-existing buffer (vs. allocated our own)? - bool borrowed_; + // The borrowed pre-existing buffer, if any (if we haven't allocated our own) + FixupStackBuffer* const borrowed_; - struct FixupStackBuffer; - - void InitViaBorrow(FixupStackBuffer* borrowed_buffer); + void InitViaBorrow(); void InitViaAllocation(size_t length); - // Returns a non-null pointer to a buffer that could be potentially borrowed. - FixupStackBuffer* Find(); - // Attempts to opportunistically borrow a small buffer in a thread- and // signal-safe manner. Returns nullptr on failure. [[nodiscard]] FixupStackBuffer* TryLock(); // Returns the borrowed buffer. - void Unlock(); + void Unlock() &&; BorrowedFixupBuffer(const BorrowedFixupBuffer&) = delete; BorrowedFixupBuffer& operator=(const BorrowedFixupBuffer&) = delete;
diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc index 35ab0a2..6b02f19 100644 --- a/absl/hash/internal/hash.cc +++ b/absl/hash/internal/hash.cc
@@ -58,7 +58,7 @@ } #ifdef ABSL_AES_INTERNAL_HAVE_X86_SIMD -uint64_t LowLevelHash33To64(const uint8_t* ptr, size_t len, uint64_t seed) { +uint64_t LowLevelHash33To64(uint64_t seed, const uint8_t* ptr, size_t len) { assert(len > 32); assert(len <= 64); __m128i state = @@ -91,7 +91,7 @@ return x64 ^ y64; } #else -uint64_t LowLevelHash33To64(const uint8_t* ptr, size_t len, uint64_t seed) { +uint64_t LowLevelHash33To64(uint64_t seed, const uint8_t* ptr, size_t len) { assert(len > 32); assert(len <= 64); uint64_t current_state = seed ^ kStaticRandomData[0] ^ len; @@ -101,7 +101,7 @@ #endif // ABSL_AES_INTERNAL_HAVE_X86_SIMD [[maybe_unused]] ABSL_ATTRIBUTE_NOINLINE uint64_t -LowLevelHashLenGt64(const void* data, size_t len, uint64_t seed) { +LowLevelHashLenGt64(uint64_t seed, const void* data, size_t len) { assert(len > 64); const uint8_t* ptr = static_cast<const uint8_t*>(data); uint64_t current_state = seed ^ kStaticRandomData[0] ^ len; @@ -149,17 +149,17 @@ return Mix32Bytes(last_32_ptr, current_state); } -[[maybe_unused]] uint64_t LowLevelHashLenGt32(const void* data, size_t len, - uint64_t seed) { +[[maybe_unused]] uint64_t LowLevelHashLenGt32(uint64_t seed, const void* data, + size_t len) { assert(len > 32); if (ABSL_PREDICT_FALSE(len > 64)) { - return LowLevelHashLenGt64(data, len, seed); + return LowLevelHashLenGt64(seed, data, len); } - return LowLevelHash33To64(static_cast<const uint8_t*>(data), len, seed); + return LowLevelHash33To64(seed, static_cast<const uint8_t*>(data), len); } ABSL_ATTRIBUTE_ALWAYS_INLINE inline uint64_t HashBlockOn32Bit( - const unsigned char* data, size_t len, uint64_t state) { + uint64_t state, const unsigned char* data, size_t len) { // TODO(b/417141985): expose and use CityHash32WithSeed. // Note: we can't use PrecombineLengthMix here because len can be up to 1024. return CombineRawImpl( @@ -168,9 +168,9 @@ } ABSL_ATTRIBUTE_NOINLINE uint64_t -SplitAndCombineOn32Bit(const unsigned char* first, size_t len, uint64_t state) { +SplitAndCombineOn32Bit(uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { - state = HashBlockOn32Bit(first, PiecewiseChunkSize(), state); + state = HashBlockOn32Bit(state, first, PiecewiseChunkSize()); len -= PiecewiseChunkSize(); first += PiecewiseChunkSize(); } @@ -185,9 +185,9 @@ } ABSL_ATTRIBUTE_ALWAYS_INLINE inline uint64_t HashBlockOn64Bit( - const unsigned char* data, size_t len, uint64_t state) { + uint64_t state, const unsigned char* data, size_t len) { #ifdef ABSL_HAVE_INTRINSIC_INT128 - return LowLevelHashLenGt32(data, len, state); + return LowLevelHashLenGt32(state, data, len); #else return hash_internal::CityHash64WithSeed(reinterpret_cast<const char*>(data), len, state); @@ -195,9 +195,9 @@ } ABSL_ATTRIBUTE_NOINLINE uint64_t -SplitAndCombineOn64Bit(const unsigned char* first, size_t len, uint64_t state) { +SplitAndCombineOn64Bit(uint64_t state, const unsigned char* first, size_t len) { while (len >= PiecewiseChunkSize()) { - state = HashBlockOn64Bit(first, PiecewiseChunkSize(), state); + state = HashBlockOn64Bit(state, first, PiecewiseChunkSize()); len -= PiecewiseChunkSize(); first += PiecewiseChunkSize(); } @@ -213,26 +213,26 @@ } // namespace -uint64_t CombineLargeContiguousImplOn32BitLengthGt8(const unsigned char* first, - size_t len, - uint64_t state) { +uint64_t CombineLargeContiguousImplOn32BitLengthGt8(uint64_t state, + const unsigned char* first, + size_t len) { assert(len > 8); assert(sizeof(size_t) == 4); // NOLINT(misc-static-assert) if (ABSL_PREDICT_TRUE(len <= PiecewiseChunkSize())) { - return HashBlockOn32Bit(first, len, state); + return HashBlockOn32Bit(state, first, len); } - return SplitAndCombineOn32Bit(first, len, state); + return SplitAndCombineOn32Bit(state, first, len); } -uint64_t CombineLargeContiguousImplOn64BitLengthGt32(const unsigned char* first, - size_t len, - uint64_t state) { +uint64_t CombineLargeContiguousImplOn64BitLengthGt32(uint64_t state, + const unsigned char* first, + size_t len) { assert(len > 32); assert(sizeof(size_t) == 8); // NOLINT(misc-static-assert) if (ABSL_PREDICT_TRUE(len <= PiecewiseChunkSize())) { - return HashBlockOn64Bit(first, len, state); + return HashBlockOn64Bit(state, first, len); } - return SplitAndCombineOn64Bit(first, len, state); + return SplitAndCombineOn64Bit(state, first, len); } ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed;
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 2f91a8b..02df7fa 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h
@@ -1030,11 +1030,12 @@ // Slow dispatch path for calls to CombineContiguousImpl with a size argument // larger than inlined size. Has the same effect as calling // CombineContiguousImpl() repeatedly with the chunk stride size. -uint64_t CombineLargeContiguousImplOn32BitLengthGt8(const unsigned char* first, - size_t len, uint64_t state); -uint64_t CombineLargeContiguousImplOn64BitLengthGt32(const unsigned char* first, - size_t len, - uint64_t state); +uint64_t CombineLargeContiguousImplOn32BitLengthGt8(uint64_t state, + const unsigned char* first, + size_t len); +uint64_t CombineLargeContiguousImplOn64BitLengthGt32(uint64_t state, + const unsigned char* first, + size_t len); ABSL_ATTRIBUTE_ALWAYS_INLINE inline uint64_t CombineSmallContiguousImpl( uint64_t state, const unsigned char* first, size_t len) { @@ -1092,7 +1093,7 @@ return CombineSmallContiguousImpl(PrecombineLengthMix(state, len), first, len); } - return CombineLargeContiguousImplOn32BitLengthGt8(first, len, state); + return CombineLargeContiguousImplOn32BitLengthGt8(state, first, len); } inline uint64_t CombineContiguousImpl( @@ -1115,7 +1116,7 @@ // We must not mix length into the state here because calling // CombineContiguousImpl twice with PiecewiseChunkSize() must be equivalent // to calling CombineLargeContiguousImpl once with 2 * PiecewiseChunkSize(). - return CombineLargeContiguousImplOn64BitLengthGt32(first, len, state); + return CombineLargeContiguousImplOn64BitLengthGt32(state, first, len); } #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \
diff --git a/absl/hash/internal/low_level_hash_test.cc b/absl/hash/internal/low_level_hash_test.cc index b4fe872..cdd279b 100644 --- a/absl/hash/internal/low_level_hash_test.cc +++ b/absl/hash/internal/low_level_hash_test.cc
@@ -442,7 +442,7 @@ auto hash_fn = [](absl::string_view s, uint64_t state) { return absl::hash_internal::CombineLargeContiguousImplOn64BitLengthGt32( - reinterpret_cast<const unsigned char*>(s.data()), s.size(), state); + state, reinterpret_cast<const unsigned char*>(s.data()), s.size()); }; #if UPDATE_GOLDEN