aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/abseil-cpp/absl/profiling/internal
diff options
context:
space:
mode:
authoranastasy888 <anastasy888@yandex-team.ru>2022-02-10 16:45:54 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:54 +0300
commit49f765d71da452ea93138a25559dfa68dd76c7f3 (patch)
tree1016041feb637349e401dcc0fa85217dd2c2c639 /contrib/restricted/abseil-cpp/absl/profiling/internal
parent7353a3fdea9c67c256980c00a2b3b67f09b23a27 (diff)
downloadydb-49f765d71da452ea93138a25559dfa68dd76c7f3.tar.gz
Restoring authorship annotation for <anastasy888@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp/absl/profiling/internal')
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc144
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h112
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make44
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc86
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h404
-rw-r--r--contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make50
6 files changed, 420 insertions, 420 deletions
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc
index 81d9a75765..fbbc693877 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc
+++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc
@@ -1,58 +1,58 @@
-// Copyright 2019 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.
-
+// Copyright 2019 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/profiling/internal/exponential_biased.h"
-
-#include <stdint.h>
-
+
+#include <stdint.h>
+
#include <algorithm>
-#include <atomic>
-#include <cmath>
-#include <limits>
-
-#include "absl/base/attributes.h"
-#include "absl/base/optimization.h"
-
-namespace absl {
+#include <atomic>
+#include <cmath>
+#include <limits>
+
+#include "absl/base/attributes.h"
+#include "absl/base/optimization.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
namespace profiling_internal {
-
-// The algorithm generates a random number between 0 and 1 and applies the
-// inverse cumulative distribution function for an exponential. Specifically:
-// Let m be the inverse of the sample period, then the probability
-// distribution function is m*exp(-mx) so the CDF is
-// p = 1 - exp(-mx), so
-// q = 1 - p = exp(-mx)
-// log_e(q) = -mx
-// -log_e(q)/m = x
-// log_2(q) * (-log_e(2) * 1/m) = x
-// In the code, q is actually in the range 1 to 2**26, hence the -26 below
+
+// The algorithm generates a random number between 0 and 1 and applies the
+// inverse cumulative distribution function for an exponential. Specifically:
+// Let m be the inverse of the sample period, then the probability
+// distribution function is m*exp(-mx) so the CDF is
+// p = 1 - exp(-mx), so
+// q = 1 - p = exp(-mx)
+// log_e(q) = -mx
+// -log_e(q)/m = x
+// log_2(q) * (-log_e(2) * 1/m) = x
+// In the code, q is actually in the range 1 to 2**26, hence the -26 below
int64_t ExponentialBiased::GetSkipCount(int64_t mean) {
- if (ABSL_PREDICT_FALSE(!initialized_)) {
- Initialize();
- }
-
- uint64_t rng = NextRandom(rng_);
- rng_ = rng;
-
- // Take the top 26 bits as the random number
- // (This plus the 1<<58 sampling bound give a max possible step of
- // 5194297183973780480 bytes.)
- // The uint32_t cast is to prevent a (hard-to-reproduce) NAN
- // under piii debug for some binaries.
- double q = static_cast<uint32_t>(rng >> (kPrngNumBits - 26)) + 1.0;
- // Put the computed p-value through the CDF of a geometric.
+ if (ABSL_PREDICT_FALSE(!initialized_)) {
+ Initialize();
+ }
+
+ uint64_t rng = NextRandom(rng_);
+ rng_ = rng;
+
+ // Take the top 26 bits as the random number
+ // (This plus the 1<<58 sampling bound give a max possible step of
+ // 5194297183973780480 bytes.)
+ // The uint32_t cast is to prevent a (hard-to-reproduce) NAN
+ // under piii debug for some binaries.
+ double q = static_cast<uint32_t>(rng >> (kPrngNumBits - 26)) + 1.0;
+ // Put the computed p-value through the CDF of a geometric.
double interval = bias_ + (std::log2(q) - 26) * (-std::log(2.0) * mean);
// Very large values of interval overflow int64_t. To avoid that, we will
// cheat and clamp any huge values to (int64_t max)/2. This is a potential
@@ -60,34 +60,34 @@ int64_t ExponentialBiased::GetSkipCount(int64_t mean) {
// not likely to come up. For example, with a mean of 1e18, the probability of
// hitting this condition is about 1/1000. For a mean of 1e17, standard
// calculators claim that this event won't happen.
- if (interval > static_cast<double>(std::numeric_limits<int64_t>::max() / 2)) {
+ if (interval > static_cast<double>(std::numeric_limits<int64_t>::max() / 2)) {
// Assume huge values are bias neutral, retain bias for next call.
- return std::numeric_limits<int64_t>::max() / 2;
- }
+ return std::numeric_limits<int64_t>::max() / 2;
+ }
double value = std::rint(interval);
bias_ = interval - value;
return value;
}
-
+
int64_t ExponentialBiased::GetStride(int64_t mean) {
return GetSkipCount(mean - 1) + 1;
-}
-
-void ExponentialBiased::Initialize() {
- // We don't get well distributed numbers from `this` so we call NextRandom() a
- // bunch to mush the bits around. We use a global_rand to handle the case
- // where the same thread (by memory address) gets created and destroyed
- // repeatedly.
- ABSL_CONST_INIT static std::atomic<uint32_t> global_rand(0);
- uint64_t r = reinterpret_cast<uint64_t>(this) +
- global_rand.fetch_add(1, std::memory_order_relaxed);
- for (int i = 0; i < 20; ++i) {
- r = NextRandom(r);
- }
- rng_ = r;
- initialized_ = true;
-}
-
+}
+
+void ExponentialBiased::Initialize() {
+ // We don't get well distributed numbers from `this` so we call NextRandom() a
+ // bunch to mush the bits around. We use a global_rand to handle the case
+ // where the same thread (by memory address) gets created and destroyed
+ // repeatedly.
+ ABSL_CONST_INIT static std::atomic<uint32_t> global_rand(0);
+ uint64_t r = reinterpret_cast<uint64_t>(this) +
+ global_rand.fetch_add(1, std::memory_order_relaxed);
+ for (int i = 0; i < 20; ++i) {
+ r = NextRandom(r);
+ }
+ rng_ = r;
+ initialized_ = true;
+}
+
} // namespace profiling_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h
index d31f7782e8..282a61e62e 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h
+++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h
@@ -1,44 +1,44 @@
-// Copyright 2019 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.
-
+// Copyright 2019 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_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_
#define ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_
-
-#include <stdint.h>
-
+
+#include <stdint.h>
+
#include "absl/base/config.h"
#include "absl/base/macros.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
namespace profiling_internal {
-
-// ExponentialBiased provides a small and fast random number generator for a
+
+// ExponentialBiased provides a small and fast random number generator for a
// rounded exponential distribution. This generator manages very little state,
// and imposes no synchronization overhead. This makes it useful in specialized
// scenarios requiring minimum overhead, such as stride based periodic sampling.
-//
+//
// ExponentialBiased provides two closely related functions, GetSkipCount() and
// GetStride(), both returning a rounded integer defining a number of events
// required before some event with a given mean probability occurs.
-//
+//
// The distribution is useful to generate a random wait time or some periodic
// event with a given mean probability. For example, if an action is supposed to
// happen on average once every 'N' events, then we can get a random 'stride'
// counting down how long before the event to happen. For example, if we'd want
// to sample one in every 1000 'Frobber' calls, our code could look like this:
-//
+//
// Frobber::Frobber() {
// stride_ = exponential_biased_.GetStride(1000);
// }
@@ -70,12 +70,12 @@ namespace profiling_internal {
// bias_ = value - rounded_value;
// return rounded_value;
//
-// This class is thread-compatible.
-class ExponentialBiased {
- public:
- // The number of bits set by NextRandom.
- static constexpr int kPrngNumBits = 48;
-
+// This class is thread-compatible.
+class ExponentialBiased {
+ public:
+ // The number of bits set by NextRandom.
+ static constexpr int kPrngNumBits = 48;
+
// `GetSkipCount()` returns the number of events to skip before some chosen
// event happens. For example, randomly tossing a coin, we will on average
// throw heads once before we get tails. We can simulate random coin tosses
@@ -91,40 +91,40 @@ class ExponentialBiased {
// }
//
int64_t GetSkipCount(int64_t mean);
-
+
// GetStride() returns the number of events required for a specific event to
// happen. See the class comments for a usage example. `GetStride()` is
// equivalent to `GetSkipCount(mean - 1) + 1`. When to use `GetStride()` or
// `GetSkipCount()` depends mostly on what best fits the use case.
int64_t GetStride(int64_t mean);
- // Computes a random number in the range [0, 1<<(kPrngNumBits+1) - 1]
- //
- // This is public to enable testing.
- static uint64_t NextRandom(uint64_t rnd);
-
- private:
- void Initialize();
-
- uint64_t rng_{0};
+ // Computes a random number in the range [0, 1<<(kPrngNumBits+1) - 1]
+ //
+ // This is public to enable testing.
+ static uint64_t NextRandom(uint64_t rnd);
+
+ private:
+ void Initialize();
+
+ uint64_t rng_{0};
double bias_{0};
- bool initialized_{false};
-};
-
-// Returns the next prng value.
-// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48
-// This is the lrand64 generator.
-inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) {
- const uint64_t prng_mult = uint64_t{0x5DEECE66D};
- const uint64_t prng_add = 0xB;
- const uint64_t prng_mod_power = 48;
- const uint64_t prng_mod_mask =
- ~((~static_cast<uint64_t>(0)) << prng_mod_power);
- return (prng_mult * rnd + prng_add) & prng_mod_mask;
-}
-
+ bool initialized_{false};
+};
+
+// Returns the next prng value.
+// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48
+// This is the lrand64 generator.
+inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) {
+ const uint64_t prng_mult = uint64_t{0x5DEECE66D};
+ const uint64_t prng_add = 0xB;
+ const uint64_t prng_mod_power = 48;
+ const uint64_t prng_mod_mask =
+ ~((~static_cast<uint64_t>(0)) << prng_mod_power);
+ return (prng_mult * rnd + prng_add) & prng_mod_mask;
+}
+
} // namespace profiling_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
+} // namespace absl
+
#endif // ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make
index 14f60647fc..0d2a2c7123 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make
@@ -1,29 +1,29 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal)
-
-SRCS(
- exponential_biased.cc
-)
-
-END()
+
+SRCS(
+ exponential_biased.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc
index a738a82c86..bc068f5b3d 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc
+++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc
@@ -1,53 +1,53 @@
-// Copyright 2019 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.
-
+// Copyright 2019 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/profiling/internal/periodic_sampler.h"
-
-#include <atomic>
-
+
+#include <atomic>
+
#include "absl/profiling/internal/exponential_biased.h"
-
-namespace absl {
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
namespace profiling_internal {
-
-int64_t PeriodicSamplerBase::GetExponentialBiased(int period) noexcept {
+
+int64_t PeriodicSamplerBase::GetExponentialBiased(int period) noexcept {
return rng_.GetStride(period);
-}
-
-bool PeriodicSamplerBase::SubtleConfirmSample() noexcept {
- int current_period = period();
-
- // Deal with period case 0 (always off) and 1 (always on)
- if (ABSL_PREDICT_FALSE(current_period < 2)) {
- stride_ = 0;
- return current_period == 1;
- }
-
- // Check if this is the first call to Sample()
- if (ABSL_PREDICT_FALSE(stride_ == 1)) {
+}
+
+bool PeriodicSamplerBase::SubtleConfirmSample() noexcept {
+ int current_period = period();
+
+ // Deal with period case 0 (always off) and 1 (always on)
+ if (ABSL_PREDICT_FALSE(current_period < 2)) {
+ stride_ = 0;
+ return current_period == 1;
+ }
+
+ // Check if this is the first call to Sample()
+ if (ABSL_PREDICT_FALSE(stride_ == 1)) {
stride_ = static_cast<uint64_t>(-GetExponentialBiased(current_period));
- if (static_cast<int64_t>(stride_) < -1) {
- ++stride_;
- return false;
- }
- }
+ if (static_cast<int64_t>(stride_) < -1) {
+ ++stride_;
+ return false;
+ }
+ }
stride_ = static_cast<uint64_t>(-GetExponentialBiased(current_period));
- return true;
-}
-
+ return true;
+}
+
} // namespace profiling_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h
index 54f0af452b..d9a3224756 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h
+++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h
@@ -1,211 +1,211 @@
-// Copyright 2019 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.
-
+// Copyright 2019 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_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_
#define ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_
-
-#include <stdint.h>
-
-#include <atomic>
-
-#include "absl/base/optimization.h"
+
+#include <stdint.h>
+
+#include <atomic>
+
+#include "absl/base/optimization.h"
#include "absl/profiling/internal/exponential_biased.h"
-
-namespace absl {
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
namespace profiling_internal {
-
-// PeriodicSamplerBase provides the basic period sampler implementation.
-//
-// This is the base class for the templated PeriodicSampler class, which holds
-// a global std::atomic value identified by a user defined tag, such that
-// each specific PeriodSampler implementation holds its own global period.
-//
-// PeriodicSamplerBase is thread-compatible except where stated otherwise.
-class PeriodicSamplerBase {
- public:
- // PeriodicSamplerBase is trivial / copyable / movable / destructible.
- PeriodicSamplerBase() = default;
- PeriodicSamplerBase(PeriodicSamplerBase&&) = default;
- PeriodicSamplerBase(const PeriodicSamplerBase&) = default;
-
- // Returns true roughly once every `period` calls. This is established by a
- // randomly picked `stride` that is counted down on each call to `Sample`.
- // This stride is picked such that the probability of `Sample()` returning
- // true is 1 in `period`.
- inline bool Sample() noexcept;
-
- // The below methods are intended for optimized use cases where the
- // size of the inlined fast path code is highly important. Applications
- // should use the `Sample()` method unless they have proof that their
- // specific use case requires the optimizations offered by these methods.
- //
- // An example of such a use case is SwissTable sampling. All sampling checks
- // are in inlined SwissTable methods, and the number of call sites is huge.
- // In this case, the inlined code size added to each translation unit calling
- // SwissTable methods is non-trivial.
- //
- // The `SubtleMaybeSample()` function spuriously returns true even if the
- // function should not be sampled, applications MUST match each call to
- // 'SubtleMaybeSample()' returning true with a `SubtleConfirmSample()` call,
- // and use the result of the latter as the sampling decision.
- // In other words: the code should logically be equivalent to:
- //
- // if (SubtleMaybeSample() && SubtleConfirmSample()) {
- // // Sample this call
- // }
- //
- // In the 'inline-size' optimized case, the `SubtleConfirmSample()` call can
- // be placed out of line, for example, the typical use case looks as follows:
- //
- // // --- frobber.h -----------
- // void FrobberSampled();
- //
- // inline void FrobberImpl() {
- // // ...
- // }
- //
- // inline void Frobber() {
- // if (ABSL_PREDICT_FALSE(sampler.SubtleMaybeSample())) {
- // FrobberSampled();
- // } else {
- // FrobberImpl();
- // }
- // }
- //
- // // --- frobber.cc -----------
- // void FrobberSampled() {
- // if (!sampler.SubtleConfirmSample())) {
- // // Spurious false positive
- // FrobberImpl();
- // return;
- // }
- //
- // // Sampled execution
- // // ...
- // }
- inline bool SubtleMaybeSample() noexcept;
- bool SubtleConfirmSample() noexcept;
-
- protected:
- // We explicitly don't use a virtual destructor as this class is never
- // virtually destroyed, and it keeps the class trivial, which avoids TLS
- // prologue and epilogue code for our TLS instances.
- ~PeriodicSamplerBase() = default;
-
- // Returns the next stride for our sampler.
- // This function is virtual for testing purposes only.
- virtual int64_t GetExponentialBiased(int period) noexcept;
-
- private:
- // Returns the current period of this sampler. Thread-safe.
- virtual int period() const noexcept = 0;
-
- // Keep and decrement stride_ as an unsigned integer, but compare the value
- // to zero casted as a signed int. clang and msvc do not create optimum code
- // if we use signed for the combined decrement and sign comparison.
- //
- // Below 3 alternative options, all compiles generate the best code
- // using the unsigned increment <---> signed int comparison option.
- //
- // Option 1:
- // int64_t stride_;
- // if (ABSL_PREDICT_TRUE(++stride_ < 0)) { ... }
- //
- // GCC x64 (OK) : https://gcc.godbolt.org/z/R5MzzA
- // GCC ppc (OK) : https://gcc.godbolt.org/z/z7NZAt
- // Clang x64 (BAD): https://gcc.godbolt.org/z/t4gPsd
- // ICC x64 (OK) : https://gcc.godbolt.org/z/rE6s8W
- // MSVC x64 (OK) : https://gcc.godbolt.org/z/ARMXqS
- //
- // Option 2:
- // int64_t stride_ = 0;
- // if (ABSL_PREDICT_TRUE(--stride_ >= 0)) { ... }
- //
- // GCC x64 (OK) : https://gcc.godbolt.org/z/jSQxYK
- // GCC ppc (OK) : https://gcc.godbolt.org/z/VJdYaA
- // Clang x64 (BAD): https://gcc.godbolt.org/z/Xm4NjX
- // ICC x64 (OK) : https://gcc.godbolt.org/z/4snaFd
- // MSVC x64 (BAD): https://gcc.godbolt.org/z/BgnEKE
- //
- // Option 3:
- // uint64_t stride_;
- // if (ABSL_PREDICT_TRUE(static_cast<int64_t>(++stride_) < 0)) { ... }
- //
- // GCC x64 (OK) : https://gcc.godbolt.org/z/bFbfPy
- // GCC ppc (OK) : https://gcc.godbolt.org/z/S9KkUE
- // Clang x64 (OK) : https://gcc.godbolt.org/z/UYzRb4
- // ICC x64 (OK) : https://gcc.godbolt.org/z/ptTNfD
- // MSVC x64 (OK) : https://gcc.godbolt.org/z/76j4-5
- uint64_t stride_ = 0;
+
+// PeriodicSamplerBase provides the basic period sampler implementation.
+//
+// This is the base class for the templated PeriodicSampler class, which holds
+// a global std::atomic value identified by a user defined tag, such that
+// each specific PeriodSampler implementation holds its own global period.
+//
+// PeriodicSamplerBase is thread-compatible except where stated otherwise.
+class PeriodicSamplerBase {
+ public:
+ // PeriodicSamplerBase is trivial / copyable / movable / destructible.
+ PeriodicSamplerBase() = default;
+ PeriodicSamplerBase(PeriodicSamplerBase&&) = default;
+ PeriodicSamplerBase(const PeriodicSamplerBase&) = default;
+
+ // Returns true roughly once every `period` calls. This is established by a
+ // randomly picked `stride` that is counted down on each call to `Sample`.
+ // This stride is picked such that the probability of `Sample()` returning
+ // true is 1 in `period`.
+ inline bool Sample() noexcept;
+
+ // The below methods are intended for optimized use cases where the
+ // size of the inlined fast path code is highly important. Applications
+ // should use the `Sample()` method unless they have proof that their
+ // specific use case requires the optimizations offered by these methods.
+ //
+ // An example of such a use case is SwissTable sampling. All sampling checks
+ // are in inlined SwissTable methods, and the number of call sites is huge.
+ // In this case, the inlined code size added to each translation unit calling
+ // SwissTable methods is non-trivial.
+ //
+ // The `SubtleMaybeSample()` function spuriously returns true even if the
+ // function should not be sampled, applications MUST match each call to
+ // 'SubtleMaybeSample()' returning true with a `SubtleConfirmSample()` call,
+ // and use the result of the latter as the sampling decision.
+ // In other words: the code should logically be equivalent to:
+ //
+ // if (SubtleMaybeSample() && SubtleConfirmSample()) {
+ // // Sample this call
+ // }
+ //
+ // In the 'inline-size' optimized case, the `SubtleConfirmSample()` call can
+ // be placed out of line, for example, the typical use case looks as follows:
+ //
+ // // --- frobber.h -----------
+ // void FrobberSampled();
+ //
+ // inline void FrobberImpl() {
+ // // ...
+ // }
+ //
+ // inline void Frobber() {
+ // if (ABSL_PREDICT_FALSE(sampler.SubtleMaybeSample())) {
+ // FrobberSampled();
+ // } else {
+ // FrobberImpl();
+ // }
+ // }
+ //
+ // // --- frobber.cc -----------
+ // void FrobberSampled() {
+ // if (!sampler.SubtleConfirmSample())) {
+ // // Spurious false positive
+ // FrobberImpl();
+ // return;
+ // }
+ //
+ // // Sampled execution
+ // // ...
+ // }
+ inline bool SubtleMaybeSample() noexcept;
+ bool SubtleConfirmSample() noexcept;
+
+ protected:
+ // We explicitly don't use a virtual destructor as this class is never
+ // virtually destroyed, and it keeps the class trivial, which avoids TLS
+ // prologue and epilogue code for our TLS instances.
+ ~PeriodicSamplerBase() = default;
+
+ // Returns the next stride for our sampler.
+ // This function is virtual for testing purposes only.
+ virtual int64_t GetExponentialBiased(int period) noexcept;
+
+ private:
+ // Returns the current period of this sampler. Thread-safe.
+ virtual int period() const noexcept = 0;
+
+ // Keep and decrement stride_ as an unsigned integer, but compare the value
+ // to zero casted as a signed int. clang and msvc do not create optimum code
+ // if we use signed for the combined decrement and sign comparison.
+ //
+ // Below 3 alternative options, all compiles generate the best code
+ // using the unsigned increment <---> signed int comparison option.
+ //
+ // Option 1:
+ // int64_t stride_;
+ // if (ABSL_PREDICT_TRUE(++stride_ < 0)) { ... }
+ //
+ // GCC x64 (OK) : https://gcc.godbolt.org/z/R5MzzA
+ // GCC ppc (OK) : https://gcc.godbolt.org/z/z7NZAt
+ // Clang x64 (BAD): https://gcc.godbolt.org/z/t4gPsd
+ // ICC x64 (OK) : https://gcc.godbolt.org/z/rE6s8W
+ // MSVC x64 (OK) : https://gcc.godbolt.org/z/ARMXqS
+ //
+ // Option 2:
+ // int64_t stride_ = 0;
+ // if (ABSL_PREDICT_TRUE(--stride_ >= 0)) { ... }
+ //
+ // GCC x64 (OK) : https://gcc.godbolt.org/z/jSQxYK
+ // GCC ppc (OK) : https://gcc.godbolt.org/z/VJdYaA
+ // Clang x64 (BAD): https://gcc.godbolt.org/z/Xm4NjX
+ // ICC x64 (OK) : https://gcc.godbolt.org/z/4snaFd
+ // MSVC x64 (BAD): https://gcc.godbolt.org/z/BgnEKE
+ //
+ // Option 3:
+ // uint64_t stride_;
+ // if (ABSL_PREDICT_TRUE(static_cast<int64_t>(++stride_) < 0)) { ... }
+ //
+ // GCC x64 (OK) : https://gcc.godbolt.org/z/bFbfPy
+ // GCC ppc (OK) : https://gcc.godbolt.org/z/S9KkUE
+ // Clang x64 (OK) : https://gcc.godbolt.org/z/UYzRb4
+ // ICC x64 (OK) : https://gcc.godbolt.org/z/ptTNfD
+ // MSVC x64 (OK) : https://gcc.godbolt.org/z/76j4-5
+ uint64_t stride_ = 0;
absl::profiling_internal::ExponentialBiased rng_;
-};
-
-inline bool PeriodicSamplerBase::SubtleMaybeSample() noexcept {
- // See comments on `stride_` for the unsigned increment / signed compare.
- if (ABSL_PREDICT_TRUE(static_cast<int64_t>(++stride_) < 0)) {
- return false;
- }
- return true;
-}
-
-inline bool PeriodicSamplerBase::Sample() noexcept {
- return ABSL_PREDICT_FALSE(SubtleMaybeSample()) ? SubtleConfirmSample()
- : false;
-}
-
-// PeriodicSampler is a concreted periodic sampler implementation.
-// The user provided Tag identifies the implementation, and is required to
-// isolate the global state of this instance from other instances.
-//
-// Typical use case:
-//
-// struct HashTablezTag {};
-// thread_local PeriodicSampler sampler;
-//
-// void HashTableSamplingLogic(...) {
-// if (sampler.Sample()) {
-// HashTableSlowSamplePath(...);
-// }
-// }
-//
-template <typename Tag, int default_period = 0>
-class PeriodicSampler final : public PeriodicSamplerBase {
- public:
- ~PeriodicSampler() = default;
-
- int period() const noexcept final {
- return period_.load(std::memory_order_relaxed);
- }
-
- // Sets the global period for this sampler. Thread-safe.
- // Setting a period of 0 disables the sampler, i.e., every call to Sample()
- // will return false. Setting a period of 1 puts the sampler in 'always on'
- // mode, i.e., every call to Sample() returns true.
- static void SetGlobalPeriod(int period) {
- period_.store(period, std::memory_order_relaxed);
- }
-
- private:
- static std::atomic<int> period_;
-};
-
-template <typename Tag, int default_period>
-std::atomic<int> PeriodicSampler<Tag, default_period>::period_(default_period);
-
+};
+
+inline bool PeriodicSamplerBase::SubtleMaybeSample() noexcept {
+ // See comments on `stride_` for the unsigned increment / signed compare.
+ if (ABSL_PREDICT_TRUE(static_cast<int64_t>(++stride_) < 0)) {
+ return false;
+ }
+ return true;
+}
+
+inline bool PeriodicSamplerBase::Sample() noexcept {
+ return ABSL_PREDICT_FALSE(SubtleMaybeSample()) ? SubtleConfirmSample()
+ : false;
+}
+
+// PeriodicSampler is a concreted periodic sampler implementation.
+// The user provided Tag identifies the implementation, and is required to
+// isolate the global state of this instance from other instances.
+//
+// Typical use case:
+//
+// struct HashTablezTag {};
+// thread_local PeriodicSampler sampler;
+//
+// void HashTableSamplingLogic(...) {
+// if (sampler.Sample()) {
+// HashTableSlowSamplePath(...);
+// }
+// }
+//
+template <typename Tag, int default_period = 0>
+class PeriodicSampler final : public PeriodicSamplerBase {
+ public:
+ ~PeriodicSampler() = default;
+
+ int period() const noexcept final {
+ return period_.load(std::memory_order_relaxed);
+ }
+
+ // Sets the global period for this sampler. Thread-safe.
+ // Setting a period of 0 disables the sampler, i.e., every call to Sample()
+ // will return false. Setting a period of 1 puts the sampler in 'always on'
+ // mode, i.e., every call to Sample() returns true.
+ static void SetGlobalPeriod(int period) {
+ period_.store(period, std::memory_order_relaxed);
+ }
+
+ private:
+ static std::atomic<int> period_;
+};
+
+template <typename Tag, int default_period>
+std::atomic<int> PeriodicSampler<Tag, default_period>::period_(default_period);
+
} // namespace profiling_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
+} // namespace absl
+
#endif // ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_
diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make
index 841a35bc53..c22319b00e 100644
--- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make
@@ -1,33 +1,33 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal)
-
-SRCS(
- periodic_sampler.cc
-)
-
-END()
+
+SRCS(
+ periodic_sampler.cc
+)
+
+END()