tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cordz_functions.cc (3227B)


      1 // Copyright 2019 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "absl/strings/internal/cordz_functions.h"
     16 
     17 #include <atomic>
     18 #include <cmath>
     19 #include <limits>
     20 #include <random>
     21 
     22 #include "absl/base/attributes.h"
     23 #include "absl/base/config.h"
     24 #include "absl/base/internal/raw_logging.h"
     25 #include "absl/profiling/internal/exponential_biased.h"
     26 
     27 namespace absl {
     28 ABSL_NAMESPACE_BEGIN
     29 namespace cord_internal {
     30 namespace {
     31 
     32 // The average interval until the next sample. A value of 0 disables profiling
     33 // while a value of 1 will profile all Cords.
     34 std::atomic<int> g_cordz_mean_interval(50000);
     35 
     36 }  // namespace
     37 
     38 #ifdef ABSL_INTERNAL_CORDZ_ENABLED
     39 
     40 // Special negative 'not initialized' per thread value for cordz_next_sample.
     41 static constexpr int64_t kInitCordzNextSample = -1;
     42 
     43 ABSL_CONST_INIT thread_local SamplingState cordz_next_sample = {
     44    kInitCordzNextSample, 1};
     45 
     46 // kIntervalIfDisabled is the number of profile-eligible events need to occur
     47 // before the code will confirm that cordz is still disabled.
     48 constexpr int64_t kIntervalIfDisabled = 1 << 16;
     49 
     50 ABSL_ATTRIBUTE_NOINLINE int64_t
     51 cordz_should_profile_slow(SamplingState& state) {
     52 
     53  thread_local absl::profiling_internal::ExponentialBiased
     54      exponential_biased_generator;
     55  int32_t mean_interval = get_cordz_mean_interval();
     56 
     57  // Check if we disabled profiling. If so, set the next sample to a "large"
     58  // number to minimize the overhead of the should_profile codepath.
     59  if (mean_interval <= 0) {
     60    state = {kIntervalIfDisabled, kIntervalIfDisabled};
     61    return 0;
     62  }
     63 
     64  // Check if we're always sampling.
     65  if (mean_interval == 1) {
     66    state = {1, 1};
     67    return 1;
     68  }
     69 
     70  if (cordz_next_sample.next_sample <= 0) {
     71    // If first check on current thread, check cordz_should_profile()
     72    // again using the created (initial) stride in cordz_next_sample.
     73    const bool initialized =
     74        cordz_next_sample.next_sample != kInitCordzNextSample;
     75    auto old_stride = state.sample_stride;
     76    auto stride = exponential_biased_generator.GetStride(mean_interval);
     77    state = {stride, stride};
     78    bool should_sample = initialized || cordz_should_profile() > 0;
     79    return should_sample ? old_stride : 0;
     80  }
     81 
     82  --state.next_sample;
     83  return 0;
     84 }
     85 
     86 void cordz_set_next_sample_for_testing(int64_t next_sample) {
     87  cordz_next_sample = {next_sample, next_sample};
     88 }
     89 
     90 #endif  // ABSL_INTERNAL_CORDZ_ENABLED
     91 
     92 int32_t get_cordz_mean_interval() {
     93  return g_cordz_mean_interval.load(std::memory_order_acquire);
     94 }
     95 
     96 void set_cordz_mean_interval(int32_t mean_interval) {
     97  g_cordz_mean_interval.store(mean_interval, std::memory_order_release);
     98 }
     99 
    100 }  // namespace cord_internal
    101 ABSL_NAMESPACE_END
    102 }  // namespace absl