Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:40:52

0001 // Copyright 2022 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 // -----------------------------------------------------------------------------
0016 // File: log/internal/conditions.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // This file contains implementation of conditional log statements, like LOG_IF
0020 // including all the ABSL_LOG_INTERNAL_..._CONDITION_... macros and
0021 // various condition classes like LogEveryNState.
0022 
0023 #ifndef ABSL_LOG_INTERNAL_CONDITIONS_H_
0024 #define ABSL_LOG_INTERNAL_CONDITIONS_H_
0025 
0026 #if defined(_WIN32) || defined(__hexagon__)
0027 #include <cstdlib>
0028 #else
0029 #include <unistd.h>
0030 #endif
0031 #include <stdlib.h>
0032 
0033 #include <atomic>
0034 #include <cstdint>
0035 
0036 #include "absl/base/attributes.h"
0037 #include "absl/base/config.h"
0038 #include "absl/log/internal/voidify.h"
0039 
0040 // `ABSL_LOG_INTERNAL_CONDITION` prefixes another macro that expands to a
0041 // temporary `LogMessage` instantiation followed by zero or more streamed
0042 // expressions.  This definition is tricky to read correctly.  It evaluates to
0043 // either
0044 //
0045 //   (void)0;
0046 //
0047 // or
0048 //
0049 //   ::absl::log_internal::Voidify() &&
0050 //       ::absl::log_internal::LogMessage(...) << "the user's message";
0051 //
0052 // If the condition is evaluable at compile time, as is often the case, it
0053 // compiles away to just one side or the other.
0054 //
0055 // Although this is not used anywhere a statement (e.g. `if`) could not go,
0056 // the ternary expression does a better job avoiding spurious diagnostics
0057 // (dangling else, missing switch case) and preserving noreturn semantics (e.g.
0058 // on `LOG(FATAL)`) without requiring braces.
0059 //
0060 // The `switch` ensures that this expansion is the beginning of a statement (as
0061 // opposed to an expression) and prevents shenanigans like
0062 // `AFunction(LOG(INFO))` and `decltype(LOG(INFO))`.  The apparently-redundant
0063 // `default` case makes the condition more amenable to Clang dataflow analysis.
0064 #define ABSL_LOG_INTERNAL_STATELESS_CONDITION(condition) \
0065   switch (0)                                             \
0066   case 0:                                                \
0067   default:                                               \
0068     !(condition) ? (void)0 : ::absl::log_internal::Voidify()&&
0069 
0070 // `ABSL_LOG_INTERNAL_STATEFUL_CONDITION` applies a condition like
0071 // `ABSL_LOG_INTERNAL_STATELESS_CONDITION` but adds to that a series of variable
0072 // declarations, including a local static object which stores the state needed
0073 // to implement the stateful macros like `LOG_EVERY_N`.
0074 //
0075 // `for`-loops are used to declare scoped variables without braces (to permit
0076 // streaming into the macro's expansion) and without the dangling-`else`
0077 // problems/diagnostics that come with `if`.
0078 //
0079 // Two more variables are declared in separate `for`-loops:
0080 //
0081 // * `COUNTER` implements a streamable token whose value when streamed is the
0082 //   number of times execution has passed through the macro.
0083 // * A boolean flag is used to prevent any of the `for`-loops from ever actually
0084 //   looping.
0085 #define ABSL_LOG_INTERNAL_STATEFUL_CONDITION(condition)             \
0086   for (bool absl_log_internal_stateful_condition_do_log(condition); \
0087        absl_log_internal_stateful_condition_do_log;                 \
0088        absl_log_internal_stateful_condition_do_log = false)         \
0089   ABSL_LOG_INTERNAL_STATEFUL_CONDITION_IMPL
0090 #define ABSL_LOG_INTERNAL_STATEFUL_CONDITION_IMPL(kind, ...)              \
0091   for (static ::absl::log_internal::Log##kind##State                      \
0092            absl_log_internal_stateful_condition_state;                    \
0093        absl_log_internal_stateful_condition_do_log &&                     \
0094        absl_log_internal_stateful_condition_state.ShouldLog(__VA_ARGS__); \
0095        absl_log_internal_stateful_condition_do_log = false)               \
0096     for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED =                   \
0097              absl_log_internal_stateful_condition_state.counter();        \
0098          absl_log_internal_stateful_condition_do_log;                     \
0099          absl_log_internal_stateful_condition_do_log = false)
0100 
0101 // `ABSL_LOG_INTERNAL_CONDITION_*` serve to combine any conditions from the
0102 // macro (e.g. `LOG_IF` or `VLOG`) with inherent conditions (e.g.
0103 // `ABSL_MIN_LOG_LEVEL`) into a single boolean expression.  We could chain
0104 // ternary operators instead, however some versions of Clang sometimes issue
0105 // spurious diagnostics after such expressions due to a control flow analysis
0106 // bug.
0107 #ifdef ABSL_MIN_LOG_LEVEL
0108 #define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
0109   ABSL_LOG_INTERNAL_##type##_CONDITION(                   \
0110       (condition) && ::absl::LogSeverity::kInfo >=        \
0111                          static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
0112 #define ABSL_LOG_INTERNAL_CONDITION_WARNING(type, condition) \
0113   ABSL_LOG_INTERNAL_##type##_CONDITION(                      \
0114       (condition) && ::absl::LogSeverity::kWarning >=        \
0115                          static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
0116 #define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
0117   ABSL_LOG_INTERNAL_##type##_CONDITION(                    \
0118       (condition) && ::absl::LogSeverity::kError >=        \
0119                          static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
0120 // NOTE: Use ternary operators instead of short-circuiting to mitigate
0121 // https://bugs.llvm.org/show_bug.cgi?id=51928.
0122 #define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition)                 \
0123   ABSL_LOG_INTERNAL_##type##_CONDITION(                                    \
0124       ((condition)                                                         \
0125            ? (::absl::LogSeverity::kFatal >=                               \
0126                       static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
0127                   ? true                                                   \
0128                   : (::absl::log_internal::AbortQuietly(), false))         \
0129            : false))
0130 // NOTE: Use ternary operators instead of short-circuiting to mitigate
0131 // https://bugs.llvm.org/show_bug.cgi?id=51928.
0132 #define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition)                \
0133   ABSL_LOG_INTERNAL_##type##_CONDITION(                                    \
0134       ((condition)                                                         \
0135            ? (::absl::LogSeverity::kFatal >=                               \
0136                       static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
0137                   ? true                                                   \
0138                   : (::absl::log_internal::ExitQuietly(), false))          \
0139            : false))
0140 #define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition)             \
0141   ABSL_LOG_INTERNAL_##type##_CONDITION(                                 \
0142       (ABSL_ASSUME(absl::kLogDebugFatal == absl::LogSeverity::kError || \
0143                    absl::kLogDebugFatal == absl::LogSeverity::kFatal),  \
0144        (condition) &&                                                   \
0145            (::absl::kLogDebugFatal >=                                   \
0146                 static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) || \
0147             (::absl::kLogDebugFatal == ::absl::LogSeverity::kFatal &&   \
0148              (::absl::log_internal::AbortQuietly(), false)))))
0149 
0150 #define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity)                            \
0151   for (int absl_log_internal_severity_loop = 1;                                \
0152        absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0)   \
0153     for (const absl::LogSeverity absl_log_internal_severity =                  \
0154              ::absl::NormalizeLogSeverity(severity);                           \
0155          absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
0156   ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL
0157 #define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition)          \
0158   ABSL_LOG_INTERNAL_##type##_CONDITION((                                  \
0159       (condition) &&                                                     \
0160           (absl_log_internal_severity >=                                 \
0161                static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) ||   \
0162            (absl_log_internal_severity == ::absl::LogSeverity::kFatal && \
0163             (::absl::log_internal::AbortQuietly(), false)))))
0164 #else  // ndef ABSL_MIN_LOG_LEVEL
0165 #define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
0166   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0167 #define ABSL_LOG_INTERNAL_CONDITION_WARNING(type, condition) \
0168   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0169 #define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
0170   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0171 #define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition) \
0172   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0173 #define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition) \
0174   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0175 #define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
0176   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0177 #define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity)                            \
0178   for (int absl_log_internal_severity_loop = 1;                                \
0179        absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0)   \
0180     for (const absl::LogSeverity absl_log_internal_severity =                  \
0181              ::absl::NormalizeLogSeverity(severity);                           \
0182          absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
0183   ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL
0184 #define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition) \
0185   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
0186 #endif  // ndef ABSL_MIN_LOG_LEVEL
0187 
0188 namespace absl {
0189 ABSL_NAMESPACE_BEGIN
0190 namespace log_internal {
0191 
0192 // Stateful condition class name should be "Log" + name + "State".
0193 class LogEveryNState final {
0194  public:
0195   bool ShouldLog(int n);
0196   uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
0197 
0198  private:
0199   std::atomic<uint32_t> counter_{0};
0200 };
0201 
0202 class LogFirstNState final {
0203  public:
0204   bool ShouldLog(int n);
0205   uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
0206 
0207  private:
0208   std::atomic<uint32_t> counter_{0};
0209 };
0210 
0211 class LogEveryPow2State final {
0212  public:
0213   bool ShouldLog();
0214   uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
0215 
0216  private:
0217   std::atomic<uint32_t> counter_{0};
0218 };
0219 
0220 class LogEveryNSecState final {
0221  public:
0222   bool ShouldLog(double seconds);
0223   uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
0224 
0225  private:
0226   std::atomic<uint32_t> counter_{0};
0227   // Cycle count according to CycleClock that we should next log at.
0228   std::atomic<int64_t> next_log_time_cycles_{0};
0229 };
0230 
0231 // Helper routines to abort the application quietly
0232 
0233 [[noreturn]] inline void AbortQuietly() { abort(); }
0234 [[noreturn]] inline void ExitQuietly() { _exit(1); }
0235 }  // namespace log_internal
0236 ABSL_NAMESPACE_END
0237 }  // namespace absl
0238 
0239 #endif  // ABSL_LOG_INTERNAL_CONDITIONS_H_