diff options
Diffstat (limited to 'absl/synchronization')
-rw-r--r-- | absl/synchronization/BUILD.bazel | 14 | ||||
-rw-r--r-- | absl/synchronization/internal/graphcycles.cc | 13 | ||||
-rw-r--r-- | absl/synchronization/internal/graphcycles.h | 5 | ||||
-rw-r--r-- | absl/synchronization/internal/graphcycles_test.cc | 19 | ||||
-rw-r--r-- | absl/synchronization/internal/kernel_timeout_test.cc | 11 | ||||
-rw-r--r-- | absl/synchronization/internal/per_thread_sem_test.cc | 6 | ||||
-rw-r--r-- | absl/synchronization/internal/waiter_test.cc | 2 | ||||
-rw-r--r-- | absl/synchronization/lifetime_test.cc | 5 | ||||
-rw-r--r-- | absl/synchronization/mutex.h | 9 |
9 files changed, 63 insertions, 21 deletions
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index de06ebdd..dafeba33 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -69,7 +69,9 @@ cc_library( "//absl/base:core_headers", "//absl/base:raw_logging_internal", "//absl/time", - ], + ] + select({ + "//conditions:default": [], + }), ) cc_test( @@ -183,7 +185,7 @@ cc_test( cc_binary( name = "blocking_counter_benchmark", - testonly = 1, + testonly = True, srcs = ["blocking_counter_benchmark.cc"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -230,7 +232,7 @@ cc_test( cc_library( name = "thread_pool", - testonly = 1, + testonly = True, hdrs = ["internal/thread_pool.h"], linkopts = ABSL_DEFAULT_LINKOPTS, visibility = [ @@ -281,7 +283,7 @@ cc_test( cc_library( name = "mutex_benchmark_common", - testonly = 1, + testonly = True, srcs = ["mutex_benchmark.cc"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -300,7 +302,7 @@ cc_library( cc_binary( name = "mutex_benchmark", - testonly = 1, + testonly = True, copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ @@ -326,7 +328,7 @@ cc_test( cc_library( name = "per_thread_sem_test_common", - testonly = 1, + testonly = True, srcs = ["internal/per_thread_sem_test.cc"], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc index 39b18482..129067c1 100644 --- a/absl/synchronization/internal/graphcycles.cc +++ b/absl/synchronization/internal/graphcycles.cc @@ -211,7 +211,7 @@ class NodeSet { Vec<int32_t> table_; uint32_t occupied_; // Count of non-empty slots (includes deleted slots) - static uint32_t Hash(int32_t a) { return static_cast<uint32_t>(a * 41); } + static uint32_t Hash(int32_t a) { return static_cast<uint32_t>(a) * 41; } // Return index for storing v. May return an empty index or deleted index uint32_t FindIndex(int32_t v) const { @@ -333,7 +333,7 @@ class PointerMap { private: // Number of buckets in hash table for pointer lookups. - static constexpr uint32_t kHashTableSize = 8171; // should be prime + static constexpr uint32_t kHashTableSize = 262139; // should be prime const Vec<Node*>* nodes_; std::array<int32_t, kHashTableSize> table_; @@ -365,6 +365,14 @@ static Node* FindNode(GraphCycles::Rep* rep, GraphId id) { return (n->version == NodeVersion(id)) ? n : nullptr; } +void GraphCycles::TestOnlyAddNodes(uint32_t n) { + uint32_t old_size = rep_->nodes_.size(); + rep_->nodes_.resize(n); + for (auto i = old_size; i < n; ++i) { + rep_->nodes_[i] = nullptr; + } +} + GraphCycles::GraphCycles() { InitArenaIfNecessary(); rep_ = new (base_internal::LowLevelAlloc::AllocWithArena(sizeof(Rep), arena)) @@ -373,6 +381,7 @@ GraphCycles::GraphCycles() { GraphCycles::~GraphCycles() { for (auto* node : rep_->nodes_) { + if (node == nullptr) { continue; } node->Node::~Node(); base_internal::LowLevelAlloc::Free(node); } diff --git a/absl/synchronization/internal/graphcycles.h b/absl/synchronization/internal/graphcycles.h index ceba33e4..08f304bc 100644 --- a/absl/synchronization/internal/graphcycles.h +++ b/absl/synchronization/internal/graphcycles.h @@ -126,6 +126,11 @@ class GraphCycles { // Expensive: should only be called from graphcycles_test.cc. bool CheckInvariants() const; + // Test-only method to add more nodes. The nodes will not be valid, and this + // method should only be used to test the behavior of the graph when it is + // very full. + void TestOnlyAddNodes(uint32_t n); + // ---------------------------------------------------- struct Rep; private: diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc index 3c6ef798..47410aad 100644 --- a/absl/synchronization/internal/graphcycles_test.cc +++ b/absl/synchronization/internal/graphcycles_test.cc @@ -14,6 +14,7 @@ #include "absl/synchronization/internal/graphcycles.h" +#include <climits> #include <map> #include <random> #include <unordered_set> @@ -458,6 +459,24 @@ TEST_F(GraphCyclesTest, ManyEdges) { CheckInvariants(g_); } +TEST(GraphCycles, IntegerOverflow) { + GraphCycles graph_cycles; + char *buf = (char *)nullptr; + GraphId prev_id = graph_cycles.GetId(buf); + buf += 1; + GraphId id = graph_cycles.GetId(buf); + ASSERT_TRUE(graph_cycles.InsertEdge(prev_id, id)); + + // INT_MAX / 40 is enough to cause an overflow when multiplied by 41. + graph_cycles.TestOnlyAddNodes(INT_MAX / 40); + + buf += 1; + GraphId newid = graph_cycles.GetId(buf); + graph_cycles.HasEdge(prev_id, newid); + + graph_cycles.RemoveNode(buf); +} + } // namespace synchronization_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/internal/kernel_timeout_test.cc b/absl/synchronization/internal/kernel_timeout_test.cc index bc546719..33962f86 100644 --- a/absl/synchronization/internal/kernel_timeout_test.cc +++ b/absl/synchronization/internal/kernel_timeout_test.cc @@ -36,7 +36,7 @@ extern "C" int __clock_gettime(clockid_t c, struct timespec* ts); extern "C" int clock_gettime(clockid_t c, struct timespec* ts) { if (c == CLOCK_MONOTONIC && !absl::synchronization_internal::KernelTimeout::SupportsSteadyClock()) { - absl::SharedBitGen gen; + thread_local absl::BitGen gen; // NOLINT ts->tv_sec = absl::Uniform(gen, 0, 1'000'000'000); ts->tv_nsec = absl::Uniform(gen, 0, 1'000'000'000); return 0; @@ -58,7 +58,8 @@ constexpr absl::Duration kTimingBound = absl::Microseconds(250); using absl::synchronization_internal::KernelTimeout; -TEST(KernelTimeout, FiniteTimes) { +// TODO(b/348224897): re-enabled when the flakiness is fixed. +TEST(KernelTimeout, DISABLED_FiniteTimes) { constexpr absl::Duration kDurationsToTest[] = { absl::ZeroDuration(), absl::Nanoseconds(1), @@ -228,7 +229,8 @@ TEST(KernelTimeout, InfinitePast) { EXPECT_EQ(t.ToChronoDuration(), std::chrono::nanoseconds(0)); } -TEST(KernelTimeout, FiniteDurations) { +// TODO(b/348224897): re-enabled when the flakiness is fixed. +TEST(KernelTimeout, DISABLED_FiniteDurations) { constexpr absl::Duration kDurationsToTest[] = { absl::ZeroDuration(), absl::Nanoseconds(1), @@ -274,7 +276,8 @@ TEST(KernelTimeout, FiniteDurations) { } } -TEST(KernelTimeout, NegativeDurations) { +// TODO(b/348224897): re-enabled when the flakiness is fixed. +TEST(KernelTimeout, DISABLED_NegativeDurations) { constexpr absl::Duration kDurationsToTest[] = { -absl::ZeroDuration(), -absl::Nanoseconds(1), diff --git a/absl/synchronization/internal/per_thread_sem_test.cc b/absl/synchronization/internal/per_thread_sem_test.cc index 24a6b548..e3cf41d7 100644 --- a/absl/synchronization/internal/per_thread_sem_test.cc +++ b/absl/synchronization/internal/per_thread_sem_test.cc @@ -159,7 +159,11 @@ TEST_F(PerThreadSemTest, Timeouts) { const absl::Duration elapsed = absl::Now() - start; // Allow for a slight early return, to account for quality of implementation // issues on various platforms. - const absl::Duration slop = absl::Milliseconds(1); + absl::Duration slop = absl::Milliseconds(1); +#ifdef _MSC_VER + // Use higher slop on MSVC due to flaky test failures. + slop = absl::Milliseconds(16); +#endif EXPECT_LE(delay - slop, elapsed) << "Wait returned " << delay - elapsed << " early (with " << slop << " slop), start time was " << start; diff --git a/absl/synchronization/internal/waiter_test.cc b/absl/synchronization/internal/waiter_test.cc index 992db29b..da138961 100644 --- a/absl/synchronization/internal/waiter_test.cc +++ b/absl/synchronization/internal/waiter_test.cc @@ -44,7 +44,7 @@ extern "C" int __clock_gettime(clockid_t c, struct timespec* ts); extern "C" int clock_gettime(clockid_t c, struct timespec* ts) { if (c == CLOCK_MONOTONIC && !absl::synchronization_internal::KernelTimeout::SupportsSteadyClock()) { - absl::SharedBitGen gen; + thread_local absl::BitGen gen; // NOLINT ts->tv_sec = absl::Uniform(gen, 0, 1'000'000'000); ts->tv_nsec = absl::Uniform(gen, 0, 1'000'000'000); return 0; diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index d5ce35a1..4c4cff64 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -123,10 +123,9 @@ class OnDestruction { }; // These tests require that the compiler correctly supports C++11 constant -// initialization... but MSVC has a known regression since v19.10 till v19.25: +// initialization... but MSVC has a known regression (since v19.10) till v19.25: // https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html -#if defined(__clang__) || \ - !(defined(_MSC_VER) && _MSC_VER > 1900 && _MSC_VER < 1925) +#if defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER < 1925) // kConstInit // Test early usage. (Declaration comes first; definitions must appear after // the test runner.) diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index d53a22bb..be3f1f56 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -148,7 +148,7 @@ struct SynchWaitParams; // // See also `MutexLock`, below, for scoped `Mutex` acquisition. -class ABSL_LOCKABLE Mutex { +class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex { public: // Creates a `Mutex` that is not held by anyone. This constructor is // typically used for Mutexes allocated on the heap or the stack. @@ -190,7 +190,7 @@ class ABSL_LOCKABLE Mutex { // If the mutex can be acquired without blocking, does so exclusively and // returns `true`. Otherwise, returns `false`. Returns `true` with high // probability if the `Mutex` was free. - bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true); + ABSL_MUST_USE_RESULT bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true); // Mutex::AssertHeld() // @@ -255,7 +255,7 @@ class ABSL_LOCKABLE Mutex { // If the mutex can be acquired without blocking, acquires this mutex for // shared access and returns `true`. Otherwise, returns `false`. Returns // `true` with high probability if the `Mutex` was free or shared. - bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true); + ABSL_MUST_USE_RESULT bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true); // Mutex::AssertReaderHeld() // @@ -281,7 +281,8 @@ class ABSL_LOCKABLE Mutex { void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->Unlock(); } - bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { + ABSL_MUST_USE_RESULT bool WriterTryLock() + ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { return this->TryLock(); } |