conditions.cc 2.7 KB

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