diff options
Diffstat (limited to 'absl/profiling')
-rw-r--r-- | absl/profiling/internal/exponential_biased_test.cc | 20 | ||||
-rw-r--r-- | absl/profiling/internal/sample_recorder.h | 20 |
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); } |