From 4b2fbb4adba905eede6c61b4494acfdb660a3bb7 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 12 Oct 2020 10:33:47 -0700 Subject: Export of internal Abseil changes -- a5af5874c1c5cc02bd2a748d455321f82b6f2a93 by Andy Getzendanner : fix compile fails with asan and -Wredundant-decls Import of https://github.com/abseil/abseil-cpp/pull/801 PiperOrigin-RevId: 336693223 -- ed9df42ab2b742386c6692c2bed015374c919d9c by Derek Mauro : Fix integer conversion warning Fixes #814 PiperOrigin-RevId: 336651814 -- 0ab4c23884e72dce17b67c1eb520f9dbb802565d by Derek Mauro : Internal change PiperOrigin-RevId: 336585378 -- eba0e3dccd52a6e91bcff84075bef0affc650b74 by Matt Kulukundis : Add bitset operations to Futex helper. PiperOrigin-RevId: 336409368 -- 8b0709a8b4500bf5f0af4b602d76a298d81645e8 by Abseil Team : Fix code indentation in a comment. PiperOrigin-RevId: 336368167 -- bc3961c87a7e7760c10319a5b0349c279f7ae3ad by Samuel Benzaquen : Improve performance of the registry: - Reduce contention - Reduce memory usage for each flag by `6*sizeof(void*)`. - Replace one immortal allocation per-flag with a single one for all the flags - Slightly improve single-threaded performance by avoiding the std::map indirections. PiperOrigin-RevId: 336365904 -- 264ad9f28f935aad8b6b1437f8bf804fa9104346 by Abseil Team : Fix typo in comment on absl::Condition. PiperOrigin-RevId: 336311680 -- b5b808a8c75ca0df7b09eff9a423ec171d80f771 by Derek Mauro : Add missing Apache license headers PiperOrigin-RevId: 336294980 -- 89446c3a4793df8b95060385cf3e219357c3db1d by Andy Soffer : Internal changes PiperOrigin-RevId: 336287465 -- 57c8be4e294881bc79a6a44b8e4bf7ecbb19b9b9 by Matt Kulukundis : Extract Futex from an implementation detail of Wait to a private interface. PiperOrigin-RevId: 336123209 GitOrigin-RevId: a5af5874c1c5cc02bd2a748d455321f82b6f2a93 Change-Id: Ie5a0ebe28e571814e3e11d4c05ca308523ccf311 --- absl/algorithm/container.h | 2 +- absl/base/internal/unscaledcycleclock.cc | 4 +- absl/container/internal/layout_test.cc | 560 ++++++++++++--------- absl/container/internal/raw_hash_set_test.cc | 7 +- absl/debugging/internal/symbolize.h | 8 +- absl/flags/BUILD.bazel | 2 + absl/flags/flag_benchmark.cc | 33 ++ absl/flags/internal/registry.h | 5 +- absl/flags/parse.cc | 5 + absl/flags/reflection.cc | 68 ++- absl/hash/hash_test.cc | 8 +- absl/hash/internal/city.cc | 18 +- absl/hash/internal/city.h | 2 +- absl/random/internal/generate_real_test.cc | 4 +- absl/strings/cord_test.cc | 14 + absl/strings/internal/str_format/arg.cc | 14 + absl/strings/internal/str_format/arg.h | 14 + absl/strings/internal/str_format/bind.cc | 14 + absl/strings/internal/str_format/bind.h | 14 + absl/strings/internal/str_format/bind_test.cc | 14 + absl/strings/internal/str_format/checker.h | 14 + absl/strings/internal/str_format/checker_test.cc | 14 + absl/strings/internal/str_format/convert_test.cc | 14 + .../internal/str_format/float_conversion.cc | 14 + .../strings/internal/str_format/float_conversion.h | 14 + absl/strings/internal/str_format/parser.cc | 14 + absl/strings/internal/str_format/parser.h | 14 + absl/strings/internal/str_format/parser_test.cc | 14 + absl/strings/str_format_test.cc | 13 + absl/synchronization/BUILD.bazel | 1 + absl/synchronization/CMakeLists.txt | 1 + absl/synchronization/internal/futex.h | 139 +++++ absl/synchronization/internal/kernel_timeout.h | 3 +- absl/synchronization/internal/waiter.cc | 70 +-- absl/synchronization/mutex.cc | 9 +- absl/synchronization/mutex.h | 10 +- absl/time/clock.cc | 4 +- absl/time/duration.cc | 2 +- absl/time/time.cc | 7 +- absl/time/time.h | 12 +- absl/time/time_test.cc | 12 +- absl/types/internal/variant.h | 2 +- absl/types/variant_test.cc | 6 +- 43 files changed, 816 insertions(+), 397 deletions(-) create mode 100644 absl/synchronization/internal/futex.h (limited to 'absl') diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index bb3d1c7c..09b91f74 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -93,7 +93,7 @@ using ContainerPointerType = // std::foo(begin(c), end(c)); // becomes // std::foo(container_algorithm_internal::begin(c), -// container_algorithm_internal::end(c)); +// container_algorithm_internal::end(c)); // These are meant for internal use only. template diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc index f1e7bbef..1545288c 100644 --- a/absl/base/internal/unscaledcycleclock.cc +++ b/absl/base/internal/unscaledcycleclock.cc @@ -123,9 +123,7 @@ double UnscaledCycleClock::Frequency() { #pragma intrinsic(__rdtsc) -int64_t UnscaledCycleClock::Now() { - return __rdtsc(); -} +int64_t UnscaledCycleClock::Now() { return __rdtsc(); } double UnscaledCycleClock::Frequency() { return base_internal::NominalCPUFrequency(); diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index 757272f1..1d7158ff 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc @@ -128,8 +128,10 @@ TEST(Layout, ElementTypes) { { using L = Layout; SameType, L::ElementTypes>(); - SameType, decltype(L::Partial())::ElementTypes>(); - SameType, decltype(L::Partial(0))::ElementTypes>(); + SameType, + decltype(L::Partial())::ElementTypes>(); + SameType, + decltype(L::Partial(0))::ElementTypes>(); } { using L = Layout; @@ -368,18 +370,21 @@ TEST(Layout, PointerByIndex) { { using L = Layout; EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer<0>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(3).Pointer<0>(p)))); EXPECT_EQ(0, Distance(p, Type(L(3).Pointer<0>(p)))); } { using L = Layout; EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer<0>(p)))); - EXPECT_EQ(12, Distance(p, Type(L::Partial(3).Pointer<1>(p)))); EXPECT_EQ(0, - Distance(p, Type(L::Partial(3, 5).Pointer<0>(p)))); + Distance(p, Type(L::Partial(3).Pointer<0>(p)))); EXPECT_EQ(12, - Distance(p, Type(L::Partial(3, 5).Pointer<1>(p)))); + Distance(p, Type(L::Partial(3).Pointer<1>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(3, 5).Pointer<0>(p)))); + EXPECT_EQ( + 12, Distance(p, Type(L::Partial(3, 5).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L(3, 5).Pointer<0>(p)))); EXPECT_EQ(12, Distance(p, Type(L(3, 5).Pointer<1>(p)))); } @@ -387,39 +392,44 @@ TEST(Layout, PointerByIndex) { using L = Layout; EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer<1>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(1).Pointer<0>(p)))); - EXPECT_EQ(4, Distance(p, Type(L::Partial(1).Pointer<1>(p)))); + EXPECT_EQ(4, + Distance(p, Type(L::Partial(1).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(5).Pointer<0>(p)))); - EXPECT_EQ(8, Distance(p, Type(L::Partial(5).Pointer<1>(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(5).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer<0>(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(0, 0).Pointer<1>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer<2>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(1, 0).Pointer<0>(p)))); - EXPECT_EQ(4, - Distance(p, Type(L::Partial(1, 0).Pointer<1>(p)))); + EXPECT_EQ( + 4, Distance(p, Type(L::Partial(1, 0).Pointer<1>(p)))); EXPECT_EQ(8, Distance(p, Type(L::Partial(1, 0).Pointer<2>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(5, 3).Pointer<0>(p)))); - EXPECT_EQ(8, - Distance(p, Type(L::Partial(5, 3).Pointer<1>(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L::Partial(5, 3).Pointer<1>(p)))); EXPECT_EQ(24, Distance(p, Type(L::Partial(5, 3).Pointer<2>(p)))); EXPECT_EQ( 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<0>(p)))); EXPECT_EQ( - 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<1>(p)))); + 0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer<1>(p)))); EXPECT_EQ( 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<2>(p)))); EXPECT_EQ( 0, Distance(p, Type(L::Partial(1, 0, 0).Pointer<0>(p)))); EXPECT_EQ( - 4, Distance(p, Type(L::Partial(1, 0, 0).Pointer<1>(p)))); + 4, + Distance(p, Type(L::Partial(1, 0, 0).Pointer<1>(p)))); EXPECT_EQ( 8, Distance(p, Type(L::Partial(1, 0, 0).Pointer<2>(p)))); EXPECT_EQ( @@ -428,7 +438,8 @@ TEST(Layout, PointerByIndex) { 24, Distance(p, Type(L::Partial(5, 3, 1).Pointer<2>(p)))); EXPECT_EQ( - 8, Distance(p, Type(L::Partial(5, 3, 1).Pointer<1>(p)))); + 8, + Distance(p, Type(L::Partial(5, 3, 1).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L(5, 3, 1).Pointer<0>(p)))); EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer<2>(p)))); EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer<1>(p)))); @@ -439,75 +450,78 @@ TEST(Layout, PointerByType) { alignas(max_align_t) const unsigned char p[100] = {}; { using L = Layout; - EXPECT_EQ(0, - Distance(p, Type(L::Partial().Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(3).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial().Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(3).Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L(3).Pointer(p)))); } { using L = Layout; - EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(0).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(0).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(1).Pointer(p)))); - EXPECT_EQ(4, - Distance(p, Type(L::Partial(1).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(5).Pointer(p)))); - EXPECT_EQ(8, - Distance(p, Type(L::Partial(5).Pointer(p)))); EXPECT_EQ( - 0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + 0, Distance(p, Type(L::Partial().Pointer(p)))); EXPECT_EQ( - 0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + 0, Distance(p, Type(L::Partial(0).Pointer(p)))); EXPECT_EQ( 0, - Distance(p, Type(L::Partial(0, 0).Pointer(p)))); - EXPECT_EQ( - 0, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + Distance(p, Type(L::Partial(0).Pointer(p)))); EXPECT_EQ( - 4, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + 0, Distance(p, Type(L::Partial(1).Pointer(p)))); EXPECT_EQ( - 8, - Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + 4, + Distance(p, Type(L::Partial(1).Pointer(p)))); EXPECT_EQ( - 0, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + 0, Distance(p, Type(L::Partial(5).Pointer(p)))); EXPECT_EQ( - 8, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + 8, + Distance(p, Type(L::Partial(5).Pointer(p)))); EXPECT_EQ( - 24, - Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + 0, + Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(0, 0).Pointer(p)))); EXPECT_EQ( 0, - Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + Distance(p, Type(L::Partial(0, 0).Pointer(p)))); EXPECT_EQ( 0, - Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type( - L::Partial(0, 0, 0).Pointer(p)))); + Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ(4, Distance(p, Type( + L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ( + 8, + Distance(p, Type(L::Partial(1, 0).Pointer(p)))); EXPECT_EQ( 0, - Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type( + L::Partial(5, 3).Pointer(p)))); EXPECT_EQ( - 4, - Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + 24, + Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ(4, Distance(p, Type( + L::Partial(1, 0, 0).Pointer(p)))); EXPECT_EQ(8, Distance(p, Type( L::Partial(1, 0, 0).Pointer(p)))); - EXPECT_EQ( - 0, - Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(5, 3, 1).Pointer(p)))); EXPECT_EQ(24, Distance(p, Type( L::Partial(5, 3, 1).Pointer(p)))); - EXPECT_EQ( - 8, - Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type( + L::Partial(5, 3, 1).Pointer(p)))); EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer(p)))); - EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L(5, 3, 1).Pointer(p)))); } } @@ -548,15 +562,18 @@ TEST(Layout, MutablePointerByIndex) { EXPECT_EQ(8, Distance(p, Type(L::Partial(5, 3).Pointer<1>(p)))); EXPECT_EQ(24, Distance(p, Type(L::Partial(5, 3).Pointer<2>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<1>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<2>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(1, 0, 0).Pointer<0>(p)))); - EXPECT_EQ(4, Distance(p, Type(L::Partial(1, 0, 0).Pointer<1>(p)))); + EXPECT_EQ(4, + Distance(p, Type(L::Partial(1, 0, 0).Pointer<1>(p)))); EXPECT_EQ(8, Distance(p, Type(L::Partial(1, 0, 0).Pointer<2>(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(5, 3, 1).Pointer<0>(p)))); EXPECT_EQ(24, Distance(p, Type(L::Partial(5, 3, 1).Pointer<2>(p)))); - EXPECT_EQ(8, Distance(p, Type(L::Partial(5, 3, 1).Pointer<1>(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(5, 3, 1).Pointer<1>(p)))); EXPECT_EQ(0, Distance(p, Type(L(5, 3, 1).Pointer<0>(p)))); EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer<2>(p)))); EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer<1>(p)))); @@ -568,48 +585,61 @@ TEST(Layout, MutablePointerByType) { { using L = Layout; EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(3).Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L(3).Pointer(p)))); } { using L = Layout; EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0).Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(1).Pointer(p)))); - EXPECT_EQ(4, Distance(p, Type(L::Partial(1).Pointer(p)))); + EXPECT_EQ(4, + Distance(p, Type(L::Partial(1).Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(5).Pointer(p)))); - EXPECT_EQ(8, Distance(p, Type(L::Partial(5).Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(5).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); - EXPECT_EQ(4, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ( + 4, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); EXPECT_EQ(8, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); - EXPECT_EQ(0, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); - EXPECT_EQ(8, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); EXPECT_EQ(24, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); EXPECT_EQ( 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); - EXPECT_EQ(4, - Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ( + 4, + Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); EXPECT_EQ( 8, Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); - EXPECT_EQ(0, - Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); EXPECT_EQ( 24, Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); - EXPECT_EQ(8, - Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ( + 8, + Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); EXPECT_EQ(0, Distance(p, Type(L(5, 3, 1).Pointer(p)))); EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer(p)))); EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer(p)))); @@ -790,67 +820,72 @@ TEST(Layout, SliceByIndexData) { { using L = Layout; EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(0).Slice<0>(p)).data())); EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); - EXPECT_EQ(0, Distance(p, Type>(L(3).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L(3).Slice<0>(p)).data())); } { using L = Layout; EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(3).Slice<0>(p)).data())); EXPECT_EQ( 0, - Distance(p, - Type>(L::Partial(3, 5).Slice<0>(p)).data())); + Distance( + p, Type>(L::Partial(3, 5).Slice<0>(p)).data())); EXPECT_EQ( 12, - Distance(p, - Type>(L::Partial(3, 5).Slice<1>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type>(L(3, 5).Slice<0>(p)).data())); - EXPECT_EQ(12, - Distance(p, Type>(L(3, 5).Slice<1>(p)).data())); + Distance( + p, Type>(L::Partial(3, 5).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L(3, 5).Slice<0>(p)).data())); + EXPECT_EQ( + 12, Distance(p, Type>(L(3, 5).Slice<1>(p)).data())); } { using L = Layout; EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(1).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(0).Slice<0>(p)).data())); EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(5).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(1).Slice<0>(p)).data())); EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(0, 0).Slice<0>(p)).data())); + p, Type>(L::Partial(5).Slice<0>(p)).data())); EXPECT_EQ( 0, - Distance(p, - Type>(L::Partial(0, 0).Slice<1>(p)).data())); + Distance( + p, Type>(L::Partial(0, 0).Slice<0>(p)).data())); EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(1, 0).Slice<0>(p)).data())); + 0, + Distance( + p, Type>(L::Partial(0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(1, 0).Slice<0>(p)).data())); EXPECT_EQ( 4, - Distance(p, - Type>(L::Partial(1, 0).Slice<1>(p)).data())); + Distance( + p, Type>(L::Partial(1, 0).Slice<1>(p)).data())); EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(5, 3).Slice<0>(p)).data())); + 0, + Distance( + p, Type>(L::Partial(5, 3).Slice<0>(p)).data())); EXPECT_EQ( 8, - Distance(p, - Type>(L::Partial(5, 3).Slice<1>(p)).data())); + Distance( + p, Type>(L::Partial(5, 3).Slice<1>(p)).data())); EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(0, 0, 0).Slice<0>(p)).data())); + p, + Type>(L::Partial(0, 0, 0).Slice<0>(p)).data())); EXPECT_EQ( 0, Distance( @@ -864,7 +899,8 @@ TEST(Layout, SliceByIndexData) { EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(1, 0, 0).Slice<0>(p)).data())); + p, + Type>(L::Partial(1, 0, 0).Slice<0>(p)).data())); EXPECT_EQ( 4, Distance( @@ -878,7 +914,8 @@ TEST(Layout, SliceByIndexData) { EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(5, 3, 1).Slice<0>(p)).data())); + p, + Type>(L::Partial(5, 3, 1).Slice<0>(p)).data())); EXPECT_EQ( 24, Distance( @@ -890,12 +927,14 @@ TEST(Layout, SliceByIndexData) { p, Type>(L::Partial(5, 3, 1).Slice<1>(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L(5, 3, 1).Slice<0>(p)).data())); + 0, + Distance(p, Type>(L(5, 3, 1).Slice<0>(p)).data())); EXPECT_EQ( 24, Distance(p, Type>(L(5, 3, 1).Slice<2>(p)).data())); EXPECT_EQ( - 8, Distance(p, Type>(L(5, 3, 1).Slice<1>(p)).data())); + 8, + Distance(p, Type>(L(5, 3, 1).Slice<1>(p)).data())); } } @@ -906,98 +945,94 @@ TEST(Layout, SliceByTypeData) { EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(0).Slice(p)).data())); + p, + Type>(L::Partial(0).Slice(p)).data())); EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(3).Slice(p)).data())); + p, + Type>(L::Partial(3).Slice(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L(3).Slice(p)).data())); + 0, + Distance(p, Type>(L(3).Slice(p)).data())); } { using L = Layout; - EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(0).Slice(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(1).Slice(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(5).Slice(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type>(L::Partial(0, 0).Slice(p)).data())); EXPECT_EQ( 0, Distance( p, - Type>(L::Partial(0, 0).Slice(p)).data())); + Type>(L::Partial(0).Slice(p)).data())); EXPECT_EQ( 0, - Distance( - p, Type>(L::Partial(1, 0).Slice(p)).data())); - EXPECT_EQ( - 4, Distance( p, - Type>(L::Partial(1, 0).Slice(p)).data())); + Type>(L::Partial(1).Slice(p)).data())); EXPECT_EQ( 0, - Distance( - p, Type>(L::Partial(5, 3).Slice(p)).data())); - EXPECT_EQ( - 8, Distance( p, - Type>(L::Partial(5, 3).Slice(p)).data())); + Type>(L::Partial(5).Slice(p)).data())); EXPECT_EQ( 0, - Distance( - p, - Type>(L::Partial(0, 0, 0).Slice(p)).data())); + Distance(p, Type>(L::Partial(0, 0).Slice(p)) + .data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(0, 0).Slice(p)) + .data())); EXPECT_EQ( 0, - Distance(p, Type>(L::Partial(0, 0, 0).Slice(p)) + Distance(p, Type>(L::Partial(1, 0).Slice(p)) .data())); - EXPECT_EQ(0, Distance(p, Type>( - L::Partial(0, 0, 0).Slice(p)) + EXPECT_EQ(4, Distance(p, Type>( + L::Partial(1, 0).Slice(p)) .data())); EXPECT_EQ( 0, - Distance( - p, - Type>(L::Partial(1, 0, 0).Slice(p)).data())); - EXPECT_EQ( - 4, - Distance(p, Type>(L::Partial(1, 0, 0).Slice(p)) + Distance(p, Type>(L::Partial(5, 3).Slice(p)) .data())); + EXPECT_EQ(8, Distance(p, Type>( + L::Partial(5, 3).Slice(p)) + .data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(0, 0, 0).Slice(p)) + .data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(0, 0, 0).Slice(p)) + .data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(0, 0, 0).Slice(p)) + .data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(1, 0, 0).Slice(p)) + .data())); + EXPECT_EQ(4, Distance(p, Type>( + L::Partial(1, 0, 0).Slice(p)) + .data())); EXPECT_EQ(8, Distance(p, Type>( L::Partial(1, 0, 0).Slice(p)) .data())); - EXPECT_EQ( - 0, - Distance( - p, - Type>(L::Partial(5, 3, 1).Slice(p)).data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(5, 3, 1).Slice(p)) + .data())); EXPECT_EQ(24, Distance(p, Type>( L::Partial(5, 3, 1).Slice(p)) .data())); - EXPECT_EQ( - 8, - Distance(p, Type>(L::Partial(5, 3, 1).Slice(p)) - .data())); + EXPECT_EQ(8, Distance(p, Type>( + L::Partial(5, 3, 1).Slice(p)) + .data())); EXPECT_EQ( 0, - Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + Distance(p, + Type>(L(5, 3, 1).Slice(p)).data())); EXPECT_EQ( 24, Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); EXPECT_EQ( - 8, Distance( - p, Type>(L(5, 3, 1).Slice(p)).data())); + 8, + Distance( + p, Type>(L(5, 3, 1).Slice(p)).data())); } } @@ -1005,18 +1040,19 @@ TEST(Layout, MutableSliceByIndexData) { alignas(max_align_t) unsigned char p[100]; { using L = Layout; - EXPECT_EQ(0, - Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); EXPECT_EQ(0, Distance(p, Type>(L(3).Slice<0>(p)).data())); } { using L = Layout; - EXPECT_EQ(0, - Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(3, 5).Slice<0>(p)).data())); + 0, Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(3, 5).Slice<0>(p)).data())); EXPECT_EQ( 12, Distance(p, Type>(L::Partial(3, 5).Slice<1>(p)).data())); @@ -1025,55 +1061,63 @@ TEST(Layout, MutableSliceByIndexData) { } { using L = Layout; - EXPECT_EQ(0, - Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type>(L::Partial(1).Slice<0>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type>(L::Partial(5).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(0, 0).Slice<0>(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(0, 0).Slice<1>(p)).data())); + 0, Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(1, 0).Slice<0>(p)).data())); + 0, Distance(p, Type>(L::Partial(1).Slice<0>(p)).data())); EXPECT_EQ( - 4, Distance(p, Type>(L::Partial(1, 0).Slice<1>(p)).data())); + 0, Distance(p, Type>(L::Partial(5).Slice<0>(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(5, 3).Slice<0>(p)).data())); + 0, + Distance(p, Type>(L::Partial(0, 0).Slice<0>(p)).data())); EXPECT_EQ( - 8, Distance(p, Type>(L::Partial(5, 3).Slice<1>(p)).data())); + 0, + Distance(p, Type>(L::Partial(0, 0).Slice<1>(p)).data())); EXPECT_EQ( 0, - Distance(p, Type>(L::Partial(0, 0, 0).Slice<0>(p)).data())); + Distance(p, Type>(L::Partial(1, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 4, + Distance(p, Type>(L::Partial(1, 0).Slice<1>(p)).data())); EXPECT_EQ( 0, - Distance(p, Type>(L::Partial(0, 0, 0).Slice<1>(p)).data())); + Distance(p, Type>(L::Partial(5, 3).Slice<0>(p)).data())); + EXPECT_EQ( + 8, + Distance(p, Type>(L::Partial(5, 3).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0, 0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0, 0, 0).Slice<1>(p)).data())); EXPECT_EQ( 0, Distance( p, Type>(L::Partial(0, 0, 0).Slice<2>(p)).data())); EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(1, 0, 0).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(1, 0, 0).Slice<0>(p)).data())); EXPECT_EQ( - 4, - Distance(p, Type>(L::Partial(1, 0, 0).Slice<1>(p)).data())); + 4, Distance( + p, Type>(L::Partial(1, 0, 0).Slice<1>(p)).data())); EXPECT_EQ( 8, Distance( p, Type>(L::Partial(1, 0, 0).Slice<2>(p)).data())); EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(5, 3, 1).Slice<0>(p)).data())); + 0, Distance( + p, Type>(L::Partial(5, 3, 1).Slice<0>(p)).data())); EXPECT_EQ( 24, Distance( p, Type>(L::Partial(5, 3, 1).Slice<2>(p)).data())); EXPECT_EQ( - 8, - Distance(p, Type>(L::Partial(5, 3, 1).Slice<1>(p)).data())); - EXPECT_EQ(0, Distance(p, Type>(L(5, 3, 1).Slice<0>(p)).data())); + 8, Distance( + p, Type>(L::Partial(5, 3, 1).Slice<1>(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L(5, 3, 1).Slice<0>(p)).data())); EXPECT_EQ(24, Distance(p, Type>(L(5, 3, 1).Slice<2>(p)).data())); - EXPECT_EQ(8, Distance(p, Type>(L(5, 3, 1).Slice<1>(p)).data())); + EXPECT_EQ(8, + Distance(p, Type>(L(5, 3, 1).Slice<1>(p)).data())); } } @@ -1082,66 +1126,84 @@ TEST(Layout, MutableSliceByTypeData) { { using L = Layout; EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(0).Slice(p)).data())); + 0, Distance( + p, Type>(L::Partial(0).Slice(p)).data())); EXPECT_EQ( - 0, - Distance(p, Type>(L::Partial(3).Slice(p)).data())); - EXPECT_EQ(0, Distance(p, Type>(L(3).Slice(p)).data())); + 0, Distance( + p, Type>(L::Partial(3).Slice(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L(3).Slice(p)).data())); } { using L = Layout; EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(0).Slice(p)).data())); + 0, + Distance(p, Type>(L::Partial(0).Slice(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(1).Slice(p)).data())); + 0, + Distance(p, Type>(L::Partial(1).Slice(p)).data())); EXPECT_EQ( - 0, Distance(p, Type>(L::Partial(5).Slice(p)).data())); + 0, + Distance(p, Type>(L::Partial(5).Slice(p)).data())); EXPECT_EQ( 0, - Distance(p, Type>(L::Partial(0, 0).Slice(p)).data())); + Distance(p, + Type>(L::Partial(0, 0).Slice(p)).data())); EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(0, 0).Slice(p)).data())); + 0, + Distance( + p, Type>(L::Partial(0, 0).Slice(p)).data())); EXPECT_EQ( 0, - Distance(p, Type>(L::Partial(1, 0).Slice(p)).data())); + Distance(p, + Type>(L::Partial(1, 0).Slice(p)).data())); EXPECT_EQ( - 4, Distance( - p, Type>(L::Partial(1, 0).Slice(p)).data())); + 4, + Distance( + p, Type>(L::Partial(1, 0).Slice(p)).data())); EXPECT_EQ( 0, - Distance(p, Type>(L::Partial(5, 3).Slice(p)).data())); + Distance(p, + Type>(L::Partial(5, 3).Slice(p)).data())); EXPECT_EQ( - 8, Distance( - p, Type>(L::Partial(5, 3).Slice(p)).data())); + 8, + Distance( + p, Type>(L::Partial(5, 3).Slice(p)).data())); EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(0, 0, 0).Slice(p)).data())); + 0, + Distance( + p, + Type>(L::Partial(0, 0, 0).Slice(p)).data())); EXPECT_EQ( 0, Distance( - p, Type>(L::Partial(0, 0, 0).Slice(p)).data())); + p, + Type>(L::Partial(0, 0, 0).Slice(p)).data())); EXPECT_EQ( 0, Distance( p, Type>(L::Partial(0, 0, 0).Slice(p)).data())); EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(1, 0, 0).Slice(p)).data())); + 0, + Distance( + p, + Type>(L::Partial(1, 0, 0).Slice(p)).data())); EXPECT_EQ( 4, Distance( - p, Type>(L::Partial(1, 0, 0).Slice(p)).data())); + p, + Type>(L::Partial(1, 0, 0).Slice(p)).data())); EXPECT_EQ( 8, Distance( p, Type>(L::Partial(1, 0, 0).Slice(p)).data())); EXPECT_EQ( - 0, Distance( - p, Type>(L::Partial(5, 3, 1).Slice(p)).data())); + 0, + Distance( + p, + Type>(L::Partial(5, 3, 1).Slice(p)).data())); EXPECT_EQ( 24, Distance( @@ -1150,14 +1212,16 @@ TEST(Layout, MutableSliceByTypeData) { EXPECT_EQ( 8, Distance( - p, Type>(L::Partial(5, 3, 1).Slice(p)).data())); - EXPECT_EQ(0, - Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + p, + Type>(L::Partial(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); EXPECT_EQ( 24, Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); EXPECT_EQ( - 8, Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + 8, + Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); } } @@ -1256,17 +1320,17 @@ TEST(Layout, MutableSlices) { } { const auto x = L::Partial(1, 2, 3); - EXPECT_THAT( - (Type, Span, Span>>(x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), - IsSameSlice(x.Slice<2>(p)))); + EXPECT_THAT((Type, Span, Span>>( + x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), + IsSameSlice(x.Slice<2>(p)))); } { const L x(1, 2, 3); - EXPECT_THAT( - (Type, Span, Span>>(x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), - IsSameSlice(x.Slice<2>(p)))); + EXPECT_THAT((Type, Span, Span>>( + x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), + IsSameSlice(x.Slice<2>(p)))); } } @@ -1398,7 +1462,8 @@ TEST(Layout, DebugString) { x.DebugString()); } { - constexpr auto x = Layout::Partial(1, 2, 3); + constexpr auto x = + Layout::Partial(1, 2, 3); EXPECT_EQ( "@0(1)[1]; @4(4)[2]; @12(1)[3]; " "@16" + @@ -1406,7 +1471,8 @@ TEST(Layout, DebugString) { x.DebugString()); } { - constexpr auto x = Layout::Partial(1, 2, 3, 4); + constexpr auto x = + Layout::Partial(1, 2, 3, 4); EXPECT_EQ( "@0(1)[1]; @4(4)[2]; @12(1)[3]; " "@16" + diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index f5ae83c4..6210eb64 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -847,7 +847,8 @@ TEST(Table, EraseMaintainsValidIterator) { std::vector CollectBadMergeKeys(size_t N) { static constexpr int kGroupSize = Group::kWidth - 1; - auto topk_range = [](size_t b, size_t e, IntTable* t) -> std::vector { + auto topk_range = [](size_t b, size_t e, + IntTable* t) -> std::vector { for (size_t i = b; i != e; ++i) { t->emplace(i); } @@ -1001,8 +1002,8 @@ using ProbeStatsPerSize = std::map; // 1. Create new table and reserve it to keys.size() * 2 // 2. Insert all keys xored with seed // 3. Collect ProbeStats from final table. -ProbeStats CollectProbeStatsOnKeysXoredWithSeed(const std::vector& keys, - size_t num_iters) { +ProbeStats CollectProbeStatsOnKeysXoredWithSeed( + const std::vector& keys, size_t num_iters) { const size_t reserve_size = keys.size() * 2; ProbeStats stats; diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h index b3729af7..4f26130f 100644 --- a/absl/debugging/internal/symbolize.h +++ b/absl/debugging/internal/symbolize.h @@ -118,16 +118,14 @@ bool RemoveAllSymbolDecorators(void); // filename != nullptr // // Returns true if the file was successfully registered. -bool RegisterFileMappingHint( - const void* start, const void* end, uint64_t offset, const char* filename); +bool RegisterFileMappingHint(const void* start, const void* end, + uint64_t offset, const char* filename); // Looks up the file mapping registered by RegisterFileMappingHint for an // address range. If there is one, the file name is stored in *filename and // *start and *end are modified to reflect the registered mapping. Returns // whether any hint was found. -bool GetFileMappingHint(const void** start, - const void** end, - uint64_t * offset, +bool GetFileMappingHint(const void** start, const void** end, uint64_t* offset, const char** filename); } // namespace debugging_internal diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 9de9e223..2bd94780 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -381,6 +381,8 @@ cc_binary( deps = [ ":flag", ":marshalling", + ":parse", + ":reflection", "//absl/strings", "//absl/time", "//absl/types:optional", diff --git a/absl/flags/flag_benchmark.cc b/absl/flags/flag_benchmark.cc index 7b52c9bc..9982b604 100644 --- a/absl/flags/flag_benchmark.cc +++ b/absl/flags/flag_benchmark.cc @@ -20,6 +20,8 @@ #include "absl/flags/flag.h" #include "absl/flags/marshalling.h" +#include "absl/flags/parse.h" +#include "absl/flags/reflection.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "absl/types/optional.h" @@ -103,6 +105,23 @@ std::string AbslUnparseFlag(const UDT&) { return ""; } BENCHMARKED_TYPES(FLAG_DEF) +// Register thousands of flags to bloat up the size of the registry. +// This mimics real life production binaries. +#define DEFINE_FLAG_0(name) ABSL_FLAG(int, name, 0, ""); +#define DEFINE_FLAG_1(name) DEFINE_FLAG_0(name##0) DEFINE_FLAG_0(name##1) +#define DEFINE_FLAG_2(name) DEFINE_FLAG_1(name##0) DEFINE_FLAG_1(name##1) +#define DEFINE_FLAG_3(name) DEFINE_FLAG_2(name##0) DEFINE_FLAG_2(name##1) +#define DEFINE_FLAG_4(name) DEFINE_FLAG_3(name##0) DEFINE_FLAG_3(name##1) +#define DEFINE_FLAG_5(name) DEFINE_FLAG_4(name##0) DEFINE_FLAG_4(name##1) +#define DEFINE_FLAG_6(name) DEFINE_FLAG_5(name##0) DEFINE_FLAG_5(name##1) +#define DEFINE_FLAG_7(name) DEFINE_FLAG_6(name##0) DEFINE_FLAG_6(name##1) +#define DEFINE_FLAG_8(name) DEFINE_FLAG_7(name##0) DEFINE_FLAG_7(name##1) +#define DEFINE_FLAG_9(name) DEFINE_FLAG_8(name##0) DEFINE_FLAG_8(name##1) +#define DEFINE_FLAG_10(name) DEFINE_FLAG_9(name##0) DEFINE_FLAG_9(name##1) +#define DEFINE_FLAG_11(name) DEFINE_FLAG_10(name##0) DEFINE_FLAG_10(name##1) +#define DEFINE_FLAG_12(name) DEFINE_FLAG_11(name##0) DEFINE_FLAG_11(name##1) +DEFINE_FLAG_12(bloat_flag_); + namespace { #define BM_GetFlag(T) \ @@ -115,6 +134,20 @@ namespace { BENCHMARKED_TYPES(BM_GetFlag) +void BM_ThreadedFindCommandLineFlag(benchmark::State& state) { + char dummy[] = "dummy"; + char* argv[] = {dummy}; + // We need to ensure that flags have been parsed. That is where the registry + // is finalized. + absl::ParseCommandLine(1, argv); + + for (auto s : state) { + benchmark::DoNotOptimize( + absl::FindCommandLineFlag("bloat_flag_010101010101")); + } +} +BENCHMARK(BM_ThreadedFindCommandLineFlag)->ThreadRange(1, 16); + } // namespace #define InvokeGetFlag(T) \ diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h index 1df2db79..a8d9eb9c 100644 --- a/absl/flags/internal/registry.h +++ b/absl/flags/internal/registry.h @@ -30,9 +30,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace flags_internal { -// Executes specified visitor for each non-retired flag in the registry. -// Requires the caller hold the registry lock. -void ForEachFlagUnlocked(std::function visitor); // Executes specified visitor for each non-retired flag in the registry. While // callback are executed, the registry is locked and can't be changed. void ForEachFlag(std::function visitor); @@ -41,6 +38,8 @@ void ForEachFlag(std::function visitor); bool RegisterCommandLineFlag(CommandLineFlag&); +void FinalizeRegistry(); + //----------------------------------------------------------------------------- // Retired registrations: // diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index 4f4bb3d5..1835a837 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -611,6 +611,11 @@ std::vector ParseCommandLineImpl(int argc, char* argv[], OnUndefinedFlag on_undef_flag) { ABSL_INTERNAL_CHECK(argc > 0, "Missing argv[0]"); + // Once parsing has started we will not have more flag registrations. + // If we did, they would be missing during parsing, which is a problem on + // itself. + flags_internal::FinalizeRegistry(); + // This routine does not return anything since we abort on failure. CheckDefaultValuesParsingRoundtrip(); diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc index d7060221..c6bf8aab 100644 --- a/absl/flags/reflection.cc +++ b/absl/flags/reflection.cc @@ -17,6 +17,7 @@ #include +#include #include #include @@ -56,21 +57,23 @@ class FlagRegistry { // Returns the flag object for the specified name, or nullptr if not found. // Will emit a warning if a 'retired' flag is specified. - CommandLineFlag* FindFlagLocked(absl::string_view name); + CommandLineFlag* FindFlag(absl::string_view name); static FlagRegistry& GlobalRegistry(); // returns a singleton registry private: friend class flags_internal::FlagSaverImpl; // reads all the flags in order // to copy them - friend void ForEachFlagUnlocked( - std::function visitor); + friend void ForEachFlag(std::function visitor); + friend void FinalizeRegistry(); - // The map from name to flag, for FindFlagLocked(). + // The map from name to flag, for FindFlag(). using FlagMap = std::map; using FlagIterator = FlagMap::iterator; using FlagConstIterator = FlagMap::const_iterator; FlagMap flags_; + std::vector flat_flags_; + std::atomic finalized_flags_{false}; absl::Mutex lock_; @@ -79,15 +82,6 @@ class FlagRegistry { FlagRegistry& operator=(const FlagRegistry&); }; -CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) { - FlagConstIterator i = flags_.find(name); - if (i == flags_.end()) { - return nullptr; - } - - return i->second; -} - namespace { class FlagRegistryLock { @@ -101,8 +95,24 @@ class FlagRegistryLock { } // namespace +CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) { + if (finalized_flags_.load(std::memory_order_acquire)) { + // We could save some gcus here if we make `Name()` be non-virtual. + // We could move the `const char*` name to the base class. + auto it = std::partition_point( + flat_flags_.begin(), flat_flags_.end(), + [=](CommandLineFlag* f) { return f->Name() < name; }); + if (it != flat_flags_.end() && (*it)->Name() == name) return *it; + } + + FlagRegistryLock frl(*this); + auto it = flags_.find(name); + return it != flags_.end() ? it->second : nullptr; +} + void FlagRegistry::RegisterFlag(CommandLineFlag& flag) { FlagRegistryLock registry_lock(*this); + std::pair ins = flags_.insert(FlagMap::value_type(flag.Name(), &flag)); if (ins.second == false) { // means the name was already in the map @@ -152,18 +162,15 @@ FlagRegistry& FlagRegistry::GlobalRegistry() { // -------------------------------------------------------------------- -void ForEachFlagUnlocked(std::function visitor) { +void ForEachFlag(std::function visitor) { FlagRegistry& registry = FlagRegistry::GlobalRegistry(); - for (FlagRegistry::FlagConstIterator i = registry.flags_.begin(); - i != registry.flags_.end(); ++i) { - visitor(*i->second); + + if (registry.finalized_flags_.load(std::memory_order_acquire)) { + for (const auto& i : registry.flat_flags_) visitor(*i); } -} -void ForEachFlag(std::function visitor) { - FlagRegistry& registry = FlagRegistry::GlobalRegistry(); FlagRegistryLock frl(registry); - ForEachFlagUnlocked(visitor); + for (const auto& i : registry.flags_) visitor(*i.second); } // -------------------------------------------------------------------- @@ -173,6 +180,21 @@ bool RegisterCommandLineFlag(CommandLineFlag& flag) { return true; } +void FinalizeRegistry() { + auto& registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + if (registry.finalized_flags_.load(std::memory_order_relaxed)) { + // Was already finalized. Ignore the second time. + return; + } + registry.flat_flags_.reserve(registry.flags_.size()); + for (const auto& f : registry.flags_) { + registry.flat_flags_.push_back(f.second); + } + registry.flags_.clear(); + registry.finalized_flags_.store(true, std::memory_order_release); +} + // -------------------------------------------------------------------- namespace { @@ -298,9 +320,7 @@ CommandLineFlag* FindCommandLineFlag(absl::string_view name) { if (name.empty()) return nullptr; flags_internal::FlagRegistry& registry = flags_internal::FlagRegistry::GlobalRegistry(); - flags_internal::FlagRegistryLock frl(registry); - - return registry.FindFlagLocked(name); + return registry.FindFlag(name); } // -------------------------------------------------------------------- diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 39ba24a8..1d2e6cf0 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -82,8 +82,8 @@ TYPED_TEST_P(HashValueIntTest, FastPath) { } REGISTER_TYPED_TEST_CASE_P(HashValueIntTest, BasicUsage, FastPath); -using IntTypes = testing::Types; +using IntTypes = testing::Types; INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueIntTest, IntTypes); enum LegacyEnum { kValue1, kValue2, kValue3 }; @@ -819,8 +819,8 @@ TYPED_TEST_P(HashIntTest, BasicUsage) { } REGISTER_TYPED_TEST_CASE_P(HashIntTest, BasicUsage); -using IntTypes = testing::Types; +using IntTypes = testing::Types; INSTANTIATE_TYPED_TEST_CASE_P(My, HashIntTest, IntTypes); struct StructWithPadding { diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index e122c184..58d4bcb1 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc @@ -253,9 +253,8 @@ static uint64_t HashLen17to32(const char *s, size_t len) { // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. -static std::pair WeakHashLen32WithSeeds(uint64_t w, uint64_t x, - uint64_t y, uint64_t z, - uint64_t a, uint64_t b) { +static std::pair WeakHashLen32WithSeeds( + uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { a += w; b = Rotate(b + a + z, 21); uint64_t c = a; @@ -266,8 +265,9 @@ static std::pair WeakHashLen32WithSeeds(uint64_t w, uint64_t } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. -static std::pair WeakHashLen32WithSeeds(const char *s, uint64_t a, - uint64_t b) { +static std::pair WeakHashLen32WithSeeds(const char *s, + uint64_t a, + uint64_t b) { return WeakHashLen32WithSeeds(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16), Fetch64(s + 24), a, b); } @@ -310,8 +310,10 @@ uint64_t CityHash64(const char *s, size_t len) { uint64_t x = Fetch64(s + len - 40); uint64_t y = Fetch64(s + len - 16) + Fetch64(s + len - 56); uint64_t z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); - std::pair v = WeakHashLen32WithSeeds(s + len - 64, len, z); - std::pair w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x); + std::pair v = + WeakHashLen32WithSeeds(s + len - 64, len, z); + std::pair w = + WeakHashLen32WithSeeds(s + len - 32, y + k1, x); x = x * k1 + Fetch64(s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. @@ -337,7 +339,7 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) { } uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, - uint64_t seed1) { + uint64_t seed1) { return HashLen16(CityHash64(s, len) - seed0, seed1); } diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h index 161c7748..9c1e7a57 100644 --- a/absl/hash/internal/city.h +++ b/absl/hash/internal/city.h @@ -71,7 +71,7 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed); // Hash function for a byte array. For convenience, two seeds are also // hashed into the result. uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, - uint64_t seed1); + uint64_t seed1); // Hash function for a byte array. Most useful in 32-bit binaries. uint32_t CityHash32(const char *s, size_t len); diff --git a/absl/random/internal/generate_real_test.cc b/absl/random/internal/generate_real_test.cc index aa02f0c2..4bdc4534 100644 --- a/absl/random/internal/generate_real_test.cc +++ b/absl/random/internal/generate_real_test.cc @@ -419,8 +419,8 @@ TEST(GenerateRealTest, ExhaustiveFloat) { }; // Rely on RandU64ToFloat generating values from greatest to least when - // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus, - // this algorithm stores the previous value, and if the new value is at + // supplied with uint64_t values from greatest (0xfff...) to least (0x0). + // Thus, this algorithm stores the previous value, and if the new value is at // greater than or equal to the previous value, then there is a collision in // the generation algorithm. // diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index 4443c828..dbed3e9a 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "absl/strings/cord.h" #include diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index 9feb2248..e28a29b1 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // // POSIX spec: // http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 3dbc1526..7040c866 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index 6980ed1d..194e21af 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "absl/strings/internal/str_format/bind.h" #include diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index 585246e7..727b2115 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ diff --git a/absl/strings/internal/str_format/bind_test.cc b/absl/strings/internal/str_format/bind_test.cc index 64790a85..1eef9c43 100644 --- a/absl/strings/internal/str_format/bind_test.cc +++ b/absl/strings/internal/str_format/bind_test.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "absl/strings/internal/str_format/bind.h" #include diff --git a/absl/strings/internal/str_format/checker.h b/absl/strings/internal/str_format/checker.h index 424c51f7..2a2601ec 100644 --- a/absl/strings/internal/str_format/checker.h +++ b/absl/strings/internal/str_format/checker.h @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc index a76d70b0..7c70f47d 100644 --- a/absl/strings/internal/str_format/checker_test.cc +++ b/absl/strings/internal/str_format/checker_test.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "gmock/gmock.h" diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc index 634ee78b..375db0a0 100644 --- a/absl/strings/internal/str_format/convert_test.cc +++ b/absl/strings/internal/str_format/convert_test.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include #include diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc index 20aeada5..d3c5f0a7 100644 --- a/absl/strings/internal/str_format/float_conversion.cc +++ b/absl/strings/internal/str_format/float_conversion.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "absl/strings/internal/str_format/float_conversion.h" #include diff --git a/absl/strings/internal/str_format/float_conversion.h b/absl/strings/internal/str_format/float_conversion.h index e78bc191..71100e71 100644 --- a/absl/strings/internal/str_format/float_conversion.h +++ b/absl/strings/internal/str_format/float_conversion.h @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc index cc55dfa9..f308d023 100644 --- a/absl/strings/internal/str_format/parser.cc +++ b/absl/strings/internal/str_format/parser.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "absl/strings/internal/str_format/parser.h" #include diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h index fffed04f..6504dd3d 100644 --- a/absl/strings/internal/str_format/parser.h +++ b/absl/strings/internal/str_format/parser.h @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc index 5aced987..a5fa1c79 100644 --- a/absl/strings/internal/str_format/parser_test.cc +++ b/absl/strings/internal/str_format/parser_test.cc @@ -1,3 +1,17 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "absl/strings/internal/str_format/parser.h" #include diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index d9fb25af..c60027ad 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -1,3 +1,16 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include "absl/strings/str_format.h" diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index b2df4131..cd4009a1 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -80,6 +80,7 @@ cc_library( "barrier.h", "blocking_counter.h", "internal/create_thread_identity.h", + "internal/futex.h", "internal/per_thread_sem.h", "internal/waiter.h", "mutex.h", diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index c255b03e..e633d0bf 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -52,6 +52,7 @@ absl_cc_library( "barrier.h" "blocking_counter.h" "internal/create_thread_identity.h" + "internal/futex.h" "internal/per_thread_sem.h" "internal/waiter.h" "mutex.h" diff --git a/absl/synchronization/internal/futex.h b/absl/synchronization/internal/futex.h new file mode 100644 index 00000000..3539f491 --- /dev/null +++ b/absl/synchronization/internal/futex.h @@ -0,0 +1,139 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ +#define ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ + +#include "absl/base/config.h" + +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +#ifdef __linux__ +#include +#include +#endif + +#include +#include +#include + +#include +#include + +#include "absl/base/optimization.h" +#include "absl/synchronization/internal/kernel_timeout.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace synchronization_internal { + +// Some Android headers are missing these definitions even though they +// support these futex operations. +#ifdef __BIONIC__ +#ifndef SYS_futex +#define SYS_futex __NR_futex +#endif +#ifndef FUTEX_WAIT_BITSET +#define FUTEX_WAIT_BITSET 9 +#endif +#ifndef FUTEX_PRIVATE_FLAG +#define FUTEX_PRIVATE_FLAG 128 +#endif +#ifndef FUTEX_CLOCK_REALTIME +#define FUTEX_CLOCK_REALTIME 256 +#endif +#ifndef FUTEX_BITSET_MATCH_ANY +#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF +#endif +#endif + +#if defined(__NR_futex_time64) && !defined(SYS_futex_time64) +#define SYS_futex_time64 __NR_futex_time64 +#endif + +#if defined(SYS_futex_time64) && !defined(SYS_futex) +#define SYS_futex SYS_futex_time64 +#endif + +class FutexImpl { + public: + static int WaitUntil(std::atomic *v, int32_t val, + KernelTimeout t) { + int err = 0; + if (t.has_timeout()) { + // https://locklessinc.com/articles/futex_cheat_sheet/ + // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time. + struct timespec abs_timeout = t.MakeAbsTimespec(); + // Atomically check that the futex value is still 0, and if it + // is, sleep until abs_timeout or until woken by FUTEX_WAKE. + err = syscall( + SYS_futex, reinterpret_cast(v), + FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val, + &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY); + } else { + // Atomically check that the futex value is still 0, and if it + // is, sleep until woken by FUTEX_WAKE. + err = syscall(SYS_futex, reinterpret_cast(v), + FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr); + } + if (ABSL_PREDICT_FALSE(err != 0)) { + err = -errno; + } + return err; + } + + static int WaitBitsetAbsoluteTimeout(std::atomic *v, int32_t val, + int32_t bits, + const struct timespec *abstime) { + int err = syscall(SYS_futex, reinterpret_cast(v), + FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, val, abstime, + nullptr, bits); + if (ABSL_PREDICT_FALSE(err != 0)) { + err = -errno; + } + return err; + } + + static int Wake(std::atomic *v, int32_t count) { + int err = syscall(SYS_futex, reinterpret_cast(v), + FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count); + if (ABSL_PREDICT_FALSE(err < 0)) { + err = -errno; + } + return err; + } + + // FUTEX_WAKE_BITSET + static int WakeBitset(std::atomic *v, int32_t count, int32_t bits) { + int err = syscall(SYS_futex, reinterpret_cast(v), + FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG, count, nullptr, + nullptr, bits); + if (ABSL_PREDICT_FALSE(err < 0)) { + err = -errno; + } + return err; + } +}; + +class Futex : public FutexImpl {}; + +} // namespace synchronization_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h index 1084e1e6..bbd4d2d7 100644 --- a/absl/synchronization/internal/kernel_timeout.h +++ b/absl/synchronization/internal/kernel_timeout.h @@ -26,6 +26,7 @@ #define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ #include + #include #include @@ -142,7 +143,7 @@ inline struct timespec KernelTimeout::MakeAbsTimespec() { struct timespec abstime; int64_t seconds = (std::min)(n / kNanosPerSecond, - int64_t{(std::numeric_limits::max)()}); + int64_t{(std::numeric_limits::max)()}); abstime.tv_sec = static_cast(seconds); abstime.tv_nsec = static_cast(n % kNanosPerSecond); return abstime; diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index b6150b9b..c51855b0 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -48,6 +48,11 @@ #include "absl/base/optimization.h" #include "absl/synchronization/internal/kernel_timeout.h" +#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX +#include "absl/synchronization/internal/futex.h" +#endif + + namespace absl { ABSL_NAMESPACE_BEGIN namespace synchronization_internal { @@ -66,71 +71,6 @@ static void MaybeBecomeIdle() { #if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX -// Some Android headers are missing these definitions even though they -// support these futex operations. -#ifdef __BIONIC__ -#ifndef SYS_futex -#define SYS_futex __NR_futex -#endif -#ifndef FUTEX_WAIT_BITSET -#define FUTEX_WAIT_BITSET 9 -#endif -#ifndef FUTEX_PRIVATE_FLAG -#define FUTEX_PRIVATE_FLAG 128 -#endif -#ifndef FUTEX_CLOCK_REALTIME -#define FUTEX_CLOCK_REALTIME 256 -#endif -#ifndef FUTEX_BITSET_MATCH_ANY -#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF -#endif -#endif - -#if defined(__NR_futex_time64) && !defined(SYS_futex_time64) -#define SYS_futex_time64 __NR_futex_time64 -#endif - -#if defined(SYS_futex_time64) && !defined(SYS_futex) -#define SYS_futex SYS_futex_time64 -#endif - -class Futex { - public: - static int WaitUntil(std::atomic *v, int32_t val, - KernelTimeout t) { - int err = 0; - if (t.has_timeout()) { - // https://locklessinc.com/articles/futex_cheat_sheet/ - // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time. - struct timespec abs_timeout = t.MakeAbsTimespec(); - // Atomically check that the futex value is still 0, and if it - // is, sleep until abs_timeout or until woken by FUTEX_WAKE. - err = syscall( - SYS_futex, reinterpret_cast(v), - FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val, - &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY); - } else { - // Atomically check that the futex value is still 0, and if it - // is, sleep until woken by FUTEX_WAKE. - err = syscall(SYS_futex, reinterpret_cast(v), - FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr); - } - if (err != 0) { - err = -errno; - } - return err; - } - - static int Wake(std::atomic *v, int32_t count) { - int err = syscall(SYS_futex, reinterpret_cast(v), - FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count); - if (ABSL_PREDICT_FALSE(err < 0)) { - err = -errno; - } - return err; - } -}; - Waiter::Waiter() { futex_.store(0, std::memory_order_relaxed); } diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 9b7f088a..63f09408 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -88,8 +88,8 @@ ABSL_CONST_INIT std::atomic synch_deadlock_detection( ABSL_CONST_INIT std::atomic synch_check_invariants(false); ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES - absl::base_internal::AtomicHook - submit_profile_data; +absl::base_internal::AtomicHook + submit_profile_data; ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook mutex_tracer; @@ -491,7 +491,7 @@ struct SynchWaitParams { std::atomic *cv_word; int64_t contention_start_cycles; // Time (in cycles) when this thread started - // to contend for the mutex. + // to contend for the mutex. }; struct SynchLocksHeld { @@ -2311,7 +2311,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { if (!cond_waiter) { // Sample lock contention events only if the (first) waiter was trying to // acquire the lock, not waiting on a condition variable or Condition. - int64_t wait_cycles = base_internal::CycleClock::Now() - enqueue_timestamp; + int64_t wait_cycles = + base_internal::CycleClock::Now() - enqueue_timestamp; mutex_tracer("slow release", this, wait_cycles); ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); submit_profile_data(enqueue_timestamp); diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 6340bd63..f686c4df 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -667,10 +667,10 @@ class Condition { // }; // mu_.Await(Condition(&reached)); // - // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReadHeld()" in the - // lambda as it may be called when the mutex is being unlocked from a scope - // holding only a reader lock, which will make the assertion not fulfilled and - // crash the binary. + // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in + // the lambda as it may be called when the mutex is being unlocked from a + // scope holding only a reader lock, which will make the assertion not + // fulfilled and crash the binary. // See class comment for performance advice. In particular, if there // might be more than one waiter for the same condition, make sure @@ -954,7 +954,7 @@ void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp)); // // This has the same memory ordering concerns as RegisterMutexProfiler() above. void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj, - int64_t wait_cycles)); + int64_t wait_cycles)); // TODO(gfalcon): Combine RegisterMutexProfiler() and RegisterMutexTracer() // into a single interface, since they are only ever called in pairs. diff --git a/absl/time/clock.cc b/absl/time/clock.cc index e5c423c7..6862e011 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -74,9 +74,7 @@ ABSL_NAMESPACE_END #if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { ABSL_NAMESPACE_BEGIN -int64_t GetCurrentTimeNanos() { - return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); -} +int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); } ABSL_NAMESPACE_END } // namespace absl #else // Use the cyclecounter-based implementation below. diff --git a/absl/time/duration.cc b/absl/time/duration.cc index eca1a6d9..4443109a 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -356,7 +356,7 @@ namespace time_internal { // the remainder. If it does not saturate, the remainder remain accurate, // but the returned quotient will over/underflow int64_t and should not be used. int64_t IDivDuration(bool satq, const Duration num, const Duration den, - Duration* rem) { + Duration* rem) { int64_t q = 0; if (IDivFastPath(num, den, &q, rem)) { return q; diff --git a/absl/time/time.cc b/absl/time/time.cc index 6bb36cb3..1ec2026e 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc @@ -60,9 +60,10 @@ inline cctz::time_point unix_epoch() { inline int64_t FloorToUnit(absl::Duration d, absl::Duration unit) { absl::Duration rem; int64_t q = absl::IDivDuration(d, unit, &rem); - return (q > 0 || - rem >= ZeroDuration() || - q == std::numeric_limits::min()) ? q : q - 1; + return (q > 0 || rem >= ZeroDuration() || + q == std::numeric_limits::min()) + ? q + : q - 1; } inline absl::Time::Breakdown InfiniteFutureBreakdown() { diff --git a/absl/time/time.h b/absl/time/time.h index 37f6131d..72508031 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -639,7 +639,7 @@ class Time { // Deprecated. Use `absl::TimeZone::CivilInfo`. struct Breakdown { - int64_t year; // year (e.g., 2013) + int64_t year; // year (e.g., 2013) int month; // month of year [1:12] int day; // day of month [1:31] int hour; // hour of day [0:23] @@ -1494,12 +1494,10 @@ constexpr Duration Hours(int64_t n) { constexpr bool operator<(Duration lhs, Duration rhs) { return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs) - : time_internal::GetRepHi(lhs) == - (std::numeric_limits::min)() - ? time_internal::GetRepLo(lhs) + 1 < - time_internal::GetRepLo(rhs) + 1 - : time_internal::GetRepLo(lhs) < - time_internal::GetRepLo(rhs); + : time_internal::GetRepHi(lhs) == (std::numeric_limits::min)() + ? time_internal::GetRepLo(lhs) + 1 < + time_internal::GetRepLo(rhs) + 1 + : time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs); } constexpr bool operator==(Duration lhs, Duration rhs) { diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index b28a99fb..cde9423f 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc @@ -1070,7 +1070,8 @@ TEST(Time, ConversionSaturation) { EXPECT_EQ("292277026596-12-04T15:30:07+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); EXPECT_EQ( - absl::UnixEpoch() + absl::Seconds(std::numeric_limits::max()), t); + absl::UnixEpoch() + absl::Seconds(std::numeric_limits::max()), + t); // Checks that we can also get the maximal Time value for a far-east zone. const absl::TimeZone plus14 = absl::FixedTimeZone(14 * 60 * 60); @@ -1078,7 +1079,8 @@ TEST(Time, ConversionSaturation) { EXPECT_EQ("292277026596-12-05T05:30:07+14:00", absl::FormatTime(absl::RFC3339_full, t, plus14)); EXPECT_EQ( - absl::UnixEpoch() + absl::Seconds(std::numeric_limits::max()), t); + absl::UnixEpoch() + absl::Seconds(std::numeric_limits::max()), + t); // One second later should push us to infinity. t = absl::FromCivil(absl::CivilSecond(292277026596, 12, 4, 15, 30, 8), utc); @@ -1092,7 +1094,8 @@ TEST(Time, ConversionSaturation) { EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", absl::FormatTime(absl::RFC3339_full, t, utc)); EXPECT_EQ( - absl::UnixEpoch() + absl::Seconds(std::numeric_limits::min()), t); + absl::UnixEpoch() + absl::Seconds(std::numeric_limits::min()), + t); // Checks that we can also get the minimal Time value for a far-west zone. const absl::TimeZone minus12 = absl::FixedTimeZone(-12 * 60 * 60); @@ -1101,7 +1104,8 @@ TEST(Time, ConversionSaturation) { EXPECT_EQ("-292277022657-01-26T20:29:52-12:00", absl::FormatTime(absl::RFC3339_full, t, minus12)); EXPECT_EQ( - absl::UnixEpoch() + absl::Seconds(std::numeric_limits::min()), t); + absl::UnixEpoch() + absl::Seconds(std::numeric_limits::min()), + t); // One second before should push us to -infinity. t = absl::FromCivil(absl::CivilSecond(-292277022657, 1, 27, 8, 29, 51), utc); diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index d404e80c..772008c7 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -45,7 +45,7 @@ ABSL_NAMESPACE_BEGIN template class variant; -ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1); +ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, static_cast(-1)); template struct variant_size; diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index cf8f7f33..cf237334 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -2311,7 +2311,8 @@ TEST(VariantTest, TestRvalueConversion) { ASSERT_TRUE(absl::holds_alternative(variant2)); EXPECT_EQ(42, absl::get(variant2)); - variant2 = ConvertVariantTo>(variant(42)); + variant2 = + ConvertVariantTo>(variant(42)); ASSERT_TRUE(absl::holds_alternative(variant2)); EXPECT_EQ(42, absl::get(variant2)); #endif // !ABSL_USES_STD_VARIANT @@ -2453,7 +2454,8 @@ TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { ConvertVariantTo>(variant(42))); EXPECT_THAT(absl::get_if(&variant2), Pointee(42)); - variant2 = ConvertVariantTo>(variant(42)); + variant2 = + ConvertVariantTo>(variant(42)); EXPECT_THAT(absl::get_if(&variant2), Pointee(42)); #endif -- cgit v1.2.3