summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-10-12 10:33:47 -0700
committerGravatar Derek Mauro <dmauro@google.com>2020-10-12 13:39:27 -0400
commit4b2fbb4adba905eede6c61b4494acfdb660a3bb7 (patch)
treed9de8cc04a7794a9269273a94ddda146fa0b67cf
parente493d6acb426542ec90db9baf749d0c521ed3302 (diff)
Export of internal Abseil changes
-- a5af5874c1c5cc02bd2a748d455321f82b6f2a93 by Andy Getzendanner <durandal@google.com>: 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 <dmauro@google.com>: Fix integer conversion warning Fixes #814 PiperOrigin-RevId: 336651814 -- 0ab4c23884e72dce17b67c1eb520f9dbb802565d by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 336585378 -- eba0e3dccd52a6e91bcff84075bef0affc650b74 by Matt Kulukundis <kfm@google.com>: Add bitset operations to Futex helper. PiperOrigin-RevId: 336409368 -- 8b0709a8b4500bf5f0af4b602d76a298d81645e8 by Abseil Team <absl-team@google.com>: Fix code indentation in a comment. PiperOrigin-RevId: 336368167 -- bc3961c87a7e7760c10319a5b0349c279f7ae3ad by Samuel Benzaquen <sbenza@google.com>: 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 <absl-team@google.com>: Fix typo in comment on absl::Condition. PiperOrigin-RevId: 336311680 -- b5b808a8c75ca0df7b09eff9a423ec171d80f771 by Derek Mauro <dmauro@google.com>: Add missing Apache license headers PiperOrigin-RevId: 336294980 -- 89446c3a4793df8b95060385cf3e219357c3db1d by Andy Soffer <asoffer@google.com>: Internal changes PiperOrigin-RevId: 336287465 -- 57c8be4e294881bc79a6a44b8e4bf7ecbb19b9b9 by Matt Kulukundis <kfm@google.com>: Extract Futex from an implementation detail of Wait to a private interface. PiperOrigin-RevId: 336123209 GitOrigin-RevId: a5af5874c1c5cc02bd2a748d455321f82b6f2a93 Change-Id: Ie5a0ebe28e571814e3e11d4c05ca308523ccf311
-rw-r--r--CMake/AbseilDll.cmake1
-rw-r--r--absl/algorithm/container.h2
-rw-r--r--absl/base/internal/unscaledcycleclock.cc4
-rw-r--r--absl/container/internal/layout_test.cc560
-rw-r--r--absl/container/internal/raw_hash_set_test.cc7
-rw-r--r--absl/debugging/internal/symbolize.h8
-rw-r--r--absl/flags/BUILD.bazel2
-rw-r--r--absl/flags/flag_benchmark.cc33
-rw-r--r--absl/flags/internal/registry.h5
-rw-r--r--absl/flags/parse.cc5
-rw-r--r--absl/flags/reflection.cc68
-rw-r--r--absl/hash/hash_test.cc8
-rw-r--r--absl/hash/internal/city.cc18
-rw-r--r--absl/hash/internal/city.h2
-rw-r--r--absl/random/internal/generate_real_test.cc4
-rw-r--r--absl/strings/cord_test.cc14
-rw-r--r--absl/strings/internal/str_format/arg.cc14
-rw-r--r--absl/strings/internal/str_format/arg.h14
-rw-r--r--absl/strings/internal/str_format/bind.cc14
-rw-r--r--absl/strings/internal/str_format/bind.h14
-rw-r--r--absl/strings/internal/str_format/bind_test.cc14
-rw-r--r--absl/strings/internal/str_format/checker.h14
-rw-r--r--absl/strings/internal/str_format/checker_test.cc14
-rw-r--r--absl/strings/internal/str_format/convert_test.cc14
-rw-r--r--absl/strings/internal/str_format/float_conversion.cc14
-rw-r--r--absl/strings/internal/str_format/float_conversion.h14
-rw-r--r--absl/strings/internal/str_format/parser.cc14
-rw-r--r--absl/strings/internal/str_format/parser.h14
-rw-r--r--absl/strings/internal/str_format/parser_test.cc14
-rw-r--r--absl/strings/str_format_test.cc13
-rw-r--r--absl/synchronization/BUILD.bazel1
-rw-r--r--absl/synchronization/CMakeLists.txt1
-rw-r--r--absl/synchronization/internal/futex.h139
-rw-r--r--absl/synchronization/internal/kernel_timeout.h3
-rw-r--r--absl/synchronization/internal/waiter.cc70
-rw-r--r--absl/synchronization/mutex.cc9
-rw-r--r--absl/synchronization/mutex.h10
-rw-r--r--absl/time/clock.cc4
-rw-r--r--absl/time/duration.cc2
-rw-r--r--absl/time/time.cc7
-rw-r--r--absl/time/time.h12
-rw-r--r--absl/time/time_test.cc12
-rw-r--r--absl/types/internal/variant.h2
-rw-r--r--absl/types/variant_test.cc6
44 files changed, 817 insertions, 397 deletions
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index cf6a8c9a..d67c4399 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -250,6 +250,7 @@ set(ABSL_INTERNAL_DLL_FILES
"synchronization/notification.h"
"synchronization/internal/create_thread_identity.cc"
"synchronization/internal/create_thread_identity.h"
+ "synchronization/internal/futex.h"
"synchronization/internal/graphcycles.cc"
"synchronization/internal/graphcycles.h"
"synchronization/internal/kernel_timeout.h"
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 <typename C>
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<int32_t, int32_t>;
SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
- SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial())::ElementTypes>();
- SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial(0))::ElementTypes>();
+ SameType<std::tuple<int32_t, int32_t>,
+ decltype(L::Partial())::ElementTypes>();
+ SameType<std::tuple<int32_t, int32_t>,
+ decltype(L::Partial(0))::ElementTypes>();
}
{
using L = Layout<int8_t, int32_t, Int128>;
@@ -368,18 +370,21 @@ TEST(Layout, PointerByIndex) {
{
using L = Layout<int32_t>;
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
}
{
using L = Layout<int32_t, int32_t>;
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
- EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
EXPECT_EQ(12,
- Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
+ EXPECT_EQ(
+ 12, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
}
@@ -387,39 +392,44 @@ TEST(Layout, PointerByIndex) {
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
- EXPECT_EQ(4, Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
+ EXPECT_EQ(4,
+ Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
- EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
+ EXPECT_EQ(8,
+ Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
EXPECT_EQ(0,
Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
EXPECT_EQ(0,
Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
EXPECT_EQ(0,
Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
- EXPECT_EQ(4,
- Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
+ EXPECT_EQ(
+ 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
EXPECT_EQ(8,
Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
EXPECT_EQ(0,
Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
- EXPECT_EQ(8,
- Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
+ EXPECT_EQ(
+ 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
EXPECT_EQ(24,
Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
EXPECT_EQ(
0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
+ 0,
+ Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
EXPECT_EQ(
0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
EXPECT_EQ(
0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
EXPECT_EQ(
- 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
+ 4,
+ Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
EXPECT_EQ(
8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
EXPECT_EQ(
@@ -428,7 +438,8 @@ TEST(Layout, PointerByIndex) {
24,
Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
EXPECT_EQ(
- 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
+ 8,
+ Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
EXPECT_EQ(8, Distance(p, Type<const int32_t*>(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<int32_t>;
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
}
{
using L = Layout<int8_t, int32_t, Int128>;
- EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
- EXPECT_EQ(4,
- Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
- EXPECT_EQ(8,
- Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
+ 0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
+ 0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
EXPECT_EQ(
0,
- Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(
- 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
+ Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
EXPECT_EQ(
- 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
+ 0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
EXPECT_EQ(
- 8,
- Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
+ 4,
+ Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
EXPECT_EQ(
- 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
+ 0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
EXPECT_EQ(
- 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
+ 8,
+ Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
EXPECT_EQ(
- 24,
- Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
+ 0,
+ Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
+ L::Partial(0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
0,
- Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
+ Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
EXPECT_EQ(
0,
- Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<const Int128*>(
- L::Partial(0, 0, 0).Pointer<Int128>(p))));
+ Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
+ L::Partial(1, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 8,
+ Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
EXPECT_EQ(
0,
- Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
+ Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
+ EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
+ L::Partial(5, 3).Pointer<int32_t>(p))));
EXPECT_EQ(
- 4,
- Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
+ 24,
+ Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
+ L::Partial(0, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
+ L::Partial(0, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const Int128*>(
+ L::Partial(0, 0, 0).Pointer<Int128>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
+ L::Partial(1, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
+ L::Partial(1, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(8, Distance(p, Type<const Int128*>(
L::Partial(1, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(
- 0,
- Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
+ EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
+ L::Partial(5, 3, 1).Pointer<int8_t>(p))));
EXPECT_EQ(24, Distance(p, Type<const Int128*>(
L::Partial(5, 3, 1).Pointer<Int128>(p))));
- EXPECT_EQ(
- 8,
- Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
+ EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
+ L::Partial(5, 3, 1).Pointer<int32_t>(p))));
EXPECT_EQ(24,
Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
- EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
}
}
@@ -548,15 +562,18 @@ TEST(Layout, MutablePointerByIndex) {
EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
- EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
+ EXPECT_EQ(4,
+ Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
EXPECT_EQ(24,
Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
- EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
+ EXPECT_EQ(8,
+ Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
@@ -568,48 +585,61 @@ TEST(Layout, MutablePointerByType) {
{
using L = Layout<int32_t>;
EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
- EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
+ EXPECT_EQ(4,
+ Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
- EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(8,
+ Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(0,
Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
EXPECT_EQ(8,
Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
- EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
+ EXPECT_EQ(0,
+ Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
EXPECT_EQ(24,
Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
- EXPECT_EQ(4,
- Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 4,
+ Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
EXPECT_EQ(
8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
- EXPECT_EQ(0,
- Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
+ EXPECT_EQ(
+ 0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
EXPECT_EQ(
24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
- EXPECT_EQ(8,
- Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
+ EXPECT_EQ(
+ 8,
+ Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
@@ -790,67 +820,72 @@ TEST(Layout, SliceByIndexData) {
{
using L = Layout<int32_t>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
- EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ EXPECT_EQ(0,
+ Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
}
{
using L = Layout<int32_t, int32_t>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
EXPECT_EQ(
0,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
EXPECT_EQ(
12,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
- EXPECT_EQ(12,
- Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 12, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
EXPECT_EQ(
0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
+ p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
EXPECT_EQ(
0,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ Distance(
+ p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
+ 0,
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(
+ p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
EXPECT_EQ(
4,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
+ 0,
+ Distance(
+ p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
EXPECT_EQ(
8,
- Distance(p,
- Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ Distance(
+ p, Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
+ p,
+ Type<Span<const int8_t>>(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<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
+ p,
+ Type<Span<const int8_t>>(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<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
+ p,
+ Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(
24,
Distance(
@@ -890,12 +927,14 @@ TEST(Layout, SliceByIndexData) {
p,
Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
+ 0,
+ Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(
24,
Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
EXPECT_EQ(
- 8, Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
+ 8,
+ Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
}
}
@@ -906,98 +945,94 @@ TEST(Layout, SliceByTypeData) {
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
+ 0,
+ Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0, Distance(
- p, Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 0,
- Distance(
- p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
0,
Distance(
p,
- Type<Span<const int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
+ Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 4,
- Distance(
p,
- Type<Span<const int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
+ Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 8,
- Distance(
p,
- Type<Span<const int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
+ Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(
- p,
- Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
+ Distance(p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(0, 0).Slice<int32_t>(p))
+ .data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p))
+ Distance(p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p))
.data()));
- EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
- L::Partial(0, 0, 0).Slice<Int128>(p))
+ EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(1, 0).Slice<int32_t>(p))
.data()));
EXPECT_EQ(
0,
- Distance(
- p,
- Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
- EXPECT_EQ(
- 4,
- Distance(p, Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p))
+ Distance(p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p))
.data()));
+ EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(5, 3).Slice<int32_t>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
+ L::Partial(0, 0, 0).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(0, 0, 0).Slice<int32_t>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
+ L::Partial(0, 0, 0).Slice<Int128>(p))
+ .data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
+ L::Partial(1, 0, 0).Slice<int8_t>(p))
+ .data()));
+ EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(1, 0, 0).Slice<int32_t>(p))
+ .data()));
EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
L::Partial(1, 0, 0).Slice<Int128>(p))
.data()));
- EXPECT_EQ(
- 0,
- Distance(
- p,
- Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
+ EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
+ L::Partial(5, 3, 1).Slice<int8_t>(p))
+ .data()));
EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
L::Partial(5, 3, 1).Slice<Int128>(p))
.data()));
- EXPECT_EQ(
- 8,
- Distance(p, Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p))
- .data()));
+ EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
+ L::Partial(5, 3, 1).Slice<int32_t>(p))
+ .data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
+ Distance(p,
+ Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
24,
Distance(p,
Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 8, Distance(
- p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
+ 8,
+ Distance(
+ p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
}
}
@@ -1005,18 +1040,19 @@ TEST(Layout, MutableSliceByIndexData) {
alignas(max_align_t) unsigned char p[100];
{
using L = Layout<int32_t>;
- EXPECT_EQ(0,
- Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data()));
}
{
using L = Layout<int32_t, int32_t>;
- EXPECT_EQ(0,
- Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
+ 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0,
+ Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
EXPECT_EQ(
12,
Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
@@ -1025,55 +1061,63 @@ TEST(Layout, MutableSliceByIndexData) {
}
{
using L = Layout<int8_t, int32_t, Int128>;
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
- EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
+ 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
+ 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
EXPECT_EQ(
- 4, Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
+ 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
- 8, Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ 0,
+ Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
+ Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 4,
+ Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
+ Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 8,
+ Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(
+ p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(
+ p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
EXPECT_EQ(
0, Distance(
p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
EXPECT_EQ(
- 4,
- Distance(p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
+ 4, Distance(
+ p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
EXPECT_EQ(
8, Distance(
p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(
24, Distance(
p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
EXPECT_EQ(
- 8,
- Distance(p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
- EXPECT_EQ(0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
+ 8, Distance(
+ p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
+ EXPECT_EQ(0,
+ Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
EXPECT_EQ(24,
Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
- EXPECT_EQ(8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
+ EXPECT_EQ(8,
+ Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
}
}
@@ -1082,66 +1126,84 @@ TEST(Layout, MutableSliceByTypeData) {
{
using L = Layout<int32_t>;
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
- 0,
- Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
- EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
+ 0, Distance(
+ p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(0,
+ Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
}
{
using L = Layout<int8_t, int32_t, Int128>;
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
- 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
+ Distance(p,
+ Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
+ 0,
+ Distance(
+ p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
+ Distance(p,
+ Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
- 4, Distance(
- p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
+ 4,
+ Distance(
+ p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
0,
- Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
+ Distance(p,
+ Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
EXPECT_EQ(
- 8, Distance(
- p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
+ 8,
+ Distance(
+ p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(
+ p,
+ Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
- p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
0,
Distance(
p,
Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(
+ p,
+ Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
EXPECT_EQ(
4,
Distance(
- p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
+ p,
+ Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
EXPECT_EQ(
8,
Distance(
p,
Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 0, Distance(
- p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
+ 0,
+ Distance(
+ p,
+ Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
24,
Distance(
@@ -1150,14 +1212,16 @@ TEST(Layout, MutableSliceByTypeData) {
EXPECT_EQ(
8,
Distance(
- p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
- EXPECT_EQ(0,
- Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
+ p,
+ Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
+ EXPECT_EQ(
+ 0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
EXPECT_EQ(
24,
Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
EXPECT_EQ(
- 8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
+ 8,
+ Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
}
}
@@ -1256,17 +1320,17 @@ TEST(Layout, MutableSlices) {
}
{
const auto x = L::Partial(1, 2, 3);
- EXPECT_THAT(
- (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
- Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
- IsSameSlice(x.Slice<2>(p))));
+ EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
+ 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<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
- Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
- IsSameSlice(x.Slice<2>(p))));
+ EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
+ 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<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
+ constexpr auto x =
+ Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
"@16" +
@@ -1406,7 +1471,8 @@ TEST(Layout, DebugString) {
x.DebugString());
}
{
- constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
+ constexpr auto x =
+ Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(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<int64_t> CollectBadMergeKeys(size_t N) {
static constexpr int kGroupSize = Group::kWidth - 1;
- auto topk_range = [](size_t b, size_t e, IntTable* t) -> std::vector<int64_t> {
+ auto topk_range = [](size_t b, size_t e,
+ IntTable* t) -> std::vector<int64_t> {
for (size_t i = b; i != e; ++i) {
t->emplace(i);
}
@@ -1001,8 +1002,8 @@ using ProbeStatsPerSize = std::map<size_t, ProbeStats>;
// 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<int64_t>& keys,
- size_t num_iters) {
+ProbeStats CollectProbeStatsOnKeysXoredWithSeed(
+ const std::vector<int64_t>& 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<void(CommandLineFlag&)> 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<void(CommandLineFlag&)> visitor);
@@ -41,6 +38,8 @@ void ForEachFlag(std::function<void(CommandLineFlag&)> 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<char*> 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 <assert.h>
+#include <atomic>
#include <map>
#include <string>
@@ -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<void(CommandLineFlag&)> visitor);
+ friend void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
+ friend void FinalizeRegistry();
- // The map from name to flag, for FindFlagLocked().
+ // The map from name to flag, for FindFlag().
using FlagMap = std::map<absl::string_view, CommandLineFlag*>;
using FlagIterator = FlagMap::iterator;
using FlagConstIterator = FlagMap::const_iterator;
FlagMap flags_;
+ std::vector<CommandLineFlag*> flat_flags_;
+ std::atomic<bool> 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<FlagIterator, bool> 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<void(CommandLineFlag&)> visitor) {
+void ForEachFlag(std::function<void(CommandLineFlag&)> 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<void(CommandLineFlag&)> 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<unsigned char, char, int, int32_t, int64_t, uint32_t,
- uint64_t, size_t>;
+using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t,
+ uint32_t, uint64_t, size_t>;
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<unsigned char, char, int, int32_t, int64_t, uint32_t,
- uint64_t, size_t>;
+using IntTypes = testing::Types<unsigned char, char, int, int32_t, int64_t,
+ uint32_t, uint64_t, size_t>;
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<uint64_t, uint64_t> WeakHashLen32WithSeeds(uint64_t w, uint64_t x,
- uint64_t y, uint64_t z,
- uint64_t a, uint64_t b) {
+static std::pair<uint64_t, uint64_t> 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<uint64_t, uint64_t> 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<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s, uint64_t a,
- uint64_t b) {
+static std::pair<uint64_t, uint64_t> 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<uint64_t, uint64_t> v = WeakHashLen32WithSeeds(s + len - 64, len, z);
- std::pair<uint64_t, uint64_t> w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
+ std::pair<uint64_t, uint64_t> v =
+ WeakHashLen32WithSeeds(s + len - 64, len, z);
+ std::pair<uint64_t, uint64_t> 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 <algorithm>
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 <cerrno>
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 <string.h>
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 <string>
#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 <errno.h>
#include <stdarg.h>
#include <stdio.h>
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 <string.h>
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 <assert.h>
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 <string.h>
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 <windows.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#ifdef __linux__
+#include <linux/futex.h>
+#include <sys/syscall.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <atomic>
+#include <cstdint>
+
+#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<int32_t> *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<int32_t *>(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<int32_t *>(v),
+ FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr);
+ }
+ if (ABSL_PREDICT_FALSE(err != 0)) {
+ err = -errno;
+ }
+ return err;
+ }
+
+ static int WaitBitsetAbsoluteTimeout(std::atomic<int32_t> *v, int32_t val,
+ int32_t bits,
+ const struct timespec *abstime) {
+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(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<int32_t> *v, int32_t count) {
+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(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<int32_t> *v, int32_t count, int32_t bits) {
+ int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(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 <time.h>
+
#include <algorithm>
#include <limits>
@@ -142,7 +143,7 @@ inline struct timespec KernelTimeout::MakeAbsTimespec() {
struct timespec abstime;
int64_t seconds = (std::min)(n / kNanosPerSecond,
- int64_t{(std::numeric_limits<time_t>::max)()});
+ int64_t{(std::numeric_limits<time_t>::max)()});
abstime.tv_sec = static_cast<time_t>(seconds);
abstime.tv_nsec = static_cast<decltype(abstime.tv_nsec)>(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<int32_t> *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<int32_t *>(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<int32_t *>(v),
- FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr);
- }
- if (err != 0) {
- err = -errno;
- }
- return err;
- }
-
- static int Wake(std::atomic<int32_t> *v, int32_t count) {
- int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(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<OnDeadlockCycle> synch_deadlock_detection(
ABSL_CONST_INIT std::atomic<bool> synch_check_invariants(false);
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
- absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)>
- submit_profile_data;
+absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)>
+ submit_profile_data;
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)(
const char *msg, const void *obj, int64_t wait_cycles)>
mutex_tracer;
@@ -491,7 +491,7 @@ struct SynchWaitParams {
std::atomic<intptr_t> *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<cctz::seconds> 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<int64_t>::min()) ? q : q - 1;
+ return (q > 0 || rem >= ZeroDuration() ||
+ q == std::numeric_limits<int64_t>::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<int64_t>::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<int64_t>::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<int64_t>::max()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::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<int64_t>::max()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::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<int64_t>::min()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::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<int64_t>::min()), t);
+ absl::UnixEpoch() + absl::Seconds(std::numeric_limits<int64_t>::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... Types>
class variant;
-ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1);
+ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, static_cast<size_t>(-1));
template <class T>
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<int32_t>(variant2));
EXPECT_EQ(42, absl::get<int32_t>(variant2));
- variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
+ variant2 =
+ ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
ASSERT_TRUE(absl::holds_alternative<uint32_t>(variant2));
EXPECT_EQ(42, absl::get<uint32_t>(variant2));
#endif // !ABSL_USES_STD_VARIANT
@@ -2453,7 +2454,8 @@ TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) {
ConvertVariantTo<variant<int32_t, uint32_t>>(variant<int32_t>(42)));
EXPECT_THAT(absl::get_if<int32_t>(&variant2), Pointee(42));
- variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
+ variant2 =
+ ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42));
EXPECT_THAT(absl::get_if<uint32_t>(&variant2), Pointee(42));
#endif