tor-browser

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

conditions.cc (2761B)


      1 // Copyright 2022 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/log/internal/conditions.h"
     16 
     17 #include <atomic>
     18 #include <cstdint>
     19 
     20 #include "absl/base/config.h"
     21 #include "absl/base/internal/cycleclock.h"
     22 
     23 namespace absl {
     24 ABSL_NAMESPACE_BEGIN
     25 namespace log_internal {
     26 namespace {
     27 
     28 // The following code behaves like AtomicStatsCounter::LossyAdd() for
     29 // speed since it is fine to lose occasional updates.
     30 // Returns old value of *counter.
     31 uint32_t LossyIncrement(std::atomic<uint32_t>* counter) {
     32  const uint32_t value = counter->load(std::memory_order_relaxed);
     33  counter->store(value + 1, std::memory_order_relaxed);
     34  return value;
     35 }
     36 
     37 }  // namespace
     38 
     39 bool LogEveryNState::ShouldLog(int n) {
     40  return n > 0 && (LossyIncrement(&counter_) % static_cast<uint32_t>(n)) == 0;
     41 }
     42 
     43 bool LogFirstNState::ShouldLog(int n) {
     44  const uint32_t counter_value = counter_.load(std::memory_order_relaxed);
     45  if (static_cast<int64_t>(counter_value) < n) {
     46    counter_.store(counter_value + 1, std::memory_order_relaxed);
     47    return true;
     48  }
     49  return false;
     50 }
     51 
     52 bool LogEveryPow2State::ShouldLog() {
     53  const uint32_t new_value = LossyIncrement(&counter_) + 1;
     54  return (new_value & (new_value - 1)) == 0;
     55 }
     56 
     57 bool LogEveryNSecState::ShouldLog(double seconds) {
     58  using absl::base_internal::CycleClock;
     59  LossyIncrement(&counter_);
     60  const int64_t now_cycles = CycleClock::Now();
     61  int64_t next_cycles = next_log_time_cycles_.load(std::memory_order_relaxed);
     62 #if defined(__myriad2__)
     63  // myriad2 does not have 8-byte compare and exchange.  Use a racy version that
     64  // is "good enough" but will over-log in the face of concurrent logging.
     65  if (now_cycles > next_cycles) {
     66    next_log_time_cycles_.store(
     67        static_cast<int64_t>(now_cycles + seconds * CycleClock::Frequency()),
     68        std::memory_order_relaxed);
     69    return true;
     70  }
     71  return false;
     72 #else
     73  do {
     74    if (now_cycles <= next_cycles) return false;
     75  } while (!next_log_time_cycles_.compare_exchange_weak(
     76      next_cycles,
     77      static_cast<int64_t>(now_cycles + seconds * CycleClock::Frequency()),
     78      std::memory_order_relaxed, std::memory_order_relaxed));
     79  return true;
     80 #endif
     81 }
     82 
     83 }  // namespace log_internal
     84 ABSL_NAMESPACE_END
     85 }  // namespace absl