aboutsummaryrefslogtreecommitdiff
path: root/absl/profiling/internal
diff options
context:
space:
mode:
Diffstat (limited to 'absl/profiling/internal')
-rw-r--r--absl/profiling/internal/exponential_biased_test.cc20
-rw-r--r--absl/profiling/internal/sample_recorder.h20
2 files changed, 25 insertions, 15 deletions
diff --git a/absl/profiling/internal/exponential_biased_test.cc b/absl/profiling/internal/exponential_biased_test.cc
index 6a6c317e..ebfbcad4 100644
--- a/absl/profiling/internal/exponential_biased_test.cc
+++ b/absl/profiling/internal/exponential_biased_test.cc
@@ -94,13 +94,14 @@ double AndersonDarlingPValue(int n, double z) {
}
double AndersonDarlingStatistic(const std::vector<double>& random_sample) {
- int n = random_sample.size();
+ size_t n = random_sample.size();
double ad_sum = 0;
- for (int i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
ad_sum += (2 * i + 1) *
std::log(random_sample[i] * (1 - random_sample[n - 1 - i]));
}
- double ad_statistic = -n - 1 / static_cast<double>(n) * ad_sum;
+ const auto n_as_double = static_cast<double>(n);
+ double ad_statistic = -n_as_double - 1 / n_as_double * ad_sum;
return ad_statistic;
}
@@ -111,14 +112,15 @@ double AndersonDarlingStatistic(const std::vector<double>& random_sample) {
// Marsaglia and Marsaglia for details.
double AndersonDarlingTest(const std::vector<double>& random_sample) {
double ad_statistic = AndersonDarlingStatistic(random_sample);
- double p = AndersonDarlingPValue(random_sample.size(), ad_statistic);
+ double p = AndersonDarlingPValue(static_cast<int>(random_sample.size()),
+ ad_statistic);
return p;
}
TEST(ExponentialBiasedTest, CoinTossDemoWithGetSkipCount) {
ExponentialBiased eb;
for (int runs = 0; runs < 10; ++runs) {
- for (int flips = eb.GetSkipCount(1); flips > 0; --flips) {
+ for (int64_t flips = eb.GetSkipCount(1); flips > 0; --flips) {
printf("head...");
}
printf("tail\n");
@@ -132,7 +134,7 @@ TEST(ExponentialBiasedTest, CoinTossDemoWithGetSkipCount) {
TEST(ExponentialBiasedTest, SampleDemoWithStride) {
ExponentialBiased eb;
- int stride = eb.GetStride(10);
+ int64_t stride = eb.GetStride(10);
int samples = 0;
for (int i = 0; i < 10000000; ++i) {
if (--stride == 0) {
@@ -147,7 +149,7 @@ TEST(ExponentialBiasedTest, SampleDemoWithStride) {
// Testing that NextRandom generates uniform random numbers. Applies the
// Anderson-Darling test for uniformity
TEST(ExponentialBiasedTest, TestNextRandom) {
- for (auto n : std::vector<int>({
+ for (auto n : std::vector<size_t>({
10, // Check short-range correlation
100, 1000,
10000 // Make sure there's no systemic error
@@ -161,7 +163,7 @@ TEST(ExponentialBiasedTest, TestNextRandom) {
}
std::vector<uint64_t> int_random_sample(n);
// Collect samples
- for (int i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
int_random_sample[i] = x;
x = ExponentialBiased::NextRandom(x);
}
@@ -169,7 +171,7 @@ TEST(ExponentialBiasedTest, TestNextRandom) {
std::sort(int_random_sample.begin(), int_random_sample.end());
std::vector<double> random_sample(n);
// Convert them to uniform randoms (in the range [0,1])
- for (int i = 0; i < n; i++) {
+ for (size_t i = 0; i < n; i++) {
random_sample[i] =
static_cast<double>(int_random_sample[i]) / max_prng_value;
}
diff --git a/absl/profiling/internal/sample_recorder.h b/absl/profiling/internal/sample_recorder.h
index 5f65983b..371f6c47 100644
--- a/absl/profiling/internal/sample_recorder.h
+++ b/absl/profiling/internal/sample_recorder.h
@@ -77,8 +77,8 @@ class SampleRecorder {
// samples that have been dropped.
int64_t Iterate(const std::function<void(const T& stack)>& f);
- int32_t GetMaxSamples() const;
- void SetMaxSamples(int32_t max);
+ size_t GetMaxSamples() const;
+ void SetMaxSamples(size_t max);
private:
void PushNew(T* sample);
@@ -88,7 +88,7 @@ class SampleRecorder {
std::atomic<size_t> dropped_samples_;
std::atomic<size_t> size_estimate_;
- std::atomic<int32_t> max_samples_{1 << 20};
+ std::atomic<size_t> max_samples_{1 << 20};
// Intrusive lock free linked lists for tracking samples.
//
@@ -186,7 +186,7 @@ T* SampleRecorder<T>::PopDead(Targs... args) {
template <typename T>
template <typename... Targs>
T* SampleRecorder<T>::Register(Targs&&... args) {
- int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed);
+ size_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed);
if (size > max_samples_.load(std::memory_order_relaxed)) {
size_estimate_.fetch_sub(1, std::memory_order_relaxed);
dropped_samples_.fetch_add(1, std::memory_order_relaxed);
@@ -199,6 +199,14 @@ T* SampleRecorder<T>::Register(Targs&&... args) {
sample = new T();
{
absl::MutexLock sample_lock(&sample->init_mu);
+ // If flag initialization happens to occur (perhaps in another thread)
+ // while in this block, it will lock `graveyard_` which is usually always
+ // locked before any sample. This will appear as a lock inversion.
+ // However, this code is run exactly once per sample, and this sample
+ // cannot be accessed until after it is returned from this method. This
+ // means that this lock state can never be recreated, so we can safely
+ // inform the deadlock detector to ignore it.
+ sample->init_mu.ForgetDeadlockInfo();
sample->PrepareForSampling(std::forward<Targs>(args)...);
}
PushNew(sample);
@@ -229,12 +237,12 @@ int64_t SampleRecorder<T>::Iterate(
}
template <typename T>
-void SampleRecorder<T>::SetMaxSamples(int32_t max) {
+void SampleRecorder<T>::SetMaxSamples(size_t max) {
max_samples_.store(max, std::memory_order_release);
}
template <typename T>
-int32_t SampleRecorder<T>::GetMaxSamples() const {
+size_t SampleRecorder<T>::GetMaxSamples() const {
return max_samples_.load(std::memory_order_acquire);
}