Back to home page

EIC code displayed by LXR

 
 

    


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

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 // vlog_config.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // This header file defines `VLogSite`, a public primitive that represents
0020 // a callsite for the `VLOG` family of macros and related libraries.
0021 // It also declares and defines multiple internal utilities used to implement
0022 // `VLOG`, such as `VLogSiteManager`.
0023 
0024 #ifndef ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
0025 #define ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
0026 
0027 // IWYU pragma: private, include "absl/log/log.h"
0028 
0029 #include <atomic>
0030 #include <cstdint>
0031 #include <functional>
0032 #include <limits>
0033 #include <type_traits>
0034 
0035 #include "absl/base/attributes.h"
0036 #include "absl/base/config.h"
0037 #include "absl/base/optimization.h"
0038 #include "absl/base/thread_annotations.h"
0039 #include "absl/strings/string_view.h"
0040 
0041 namespace absl {
0042 ABSL_NAMESPACE_BEGIN
0043 namespace log_internal {
0044 
0045 class SyntheticBinary;
0046 class VLogSite;
0047 
0048 int RegisterAndInitialize(VLogSite* v);
0049 void UpdateVLogSites();
0050 constexpr int kUseFlag = (std::numeric_limits<int16_t>::min)();
0051 
0052 // Represents a unique callsite for a `VLOG()` or `VLOG_IS_ON()` call.
0053 //
0054 // Libraries that provide `VLOG`-like functionality should use this to
0055 // efficiently handle --vmodule.
0056 //
0057 // VLogSite objects must not be destroyed until the program exits. Doing so will
0058 // probably yield nasty segfaults in VLogSiteManager::UpdateLogSites(). The
0059 // recommendation is to make all such objects function-local statics.
0060 class VLogSite final {
0061  public:
0062   // `f` must not be destroyed until the program exits.
0063   explicit constexpr VLogSite(const char* f)
0064       : file_(f), v_(kUninitialized), next_(nullptr) {}
0065   VLogSite(const VLogSite&) = delete;
0066   VLogSite& operator=(const VLogSite&) = delete;
0067 
0068   // Inlining the function yields a ~3x performance improvement at the cost of a
0069   // 1.5x code size increase at the call site.
0070   // Takes locks but does not allocate memory.
0071   ABSL_ATTRIBUTE_ALWAYS_INLINE
0072   bool IsEnabled(int level) {
0073     int stale_v = v_.load(std::memory_order_relaxed);
0074     if (ABSL_PREDICT_TRUE(level > stale_v)) {
0075       return false;
0076     }
0077 
0078     // We put everything other than the fast path, i.e. vlogging is initialized
0079     // but not on, behind an out-of-line function to reduce code size.
0080     // "level" is almost always a call-site constant, so we can save a bit
0081     // of code space by special-casing for a few common levels.
0082 #if ABSL_HAVE_BUILTIN(__builtin_constant_p) || defined(__GNUC__)
0083     if (__builtin_constant_p(level)) {
0084       if (level == 0) return SlowIsEnabled0(stale_v);
0085       if (level == 1) return SlowIsEnabled1(stale_v);
0086       if (level == 2) return SlowIsEnabled2(stale_v);
0087       if (level == 3) return SlowIsEnabled3(stale_v);
0088       if (level == 4) return SlowIsEnabled4(stale_v);
0089       if (level == 5) return SlowIsEnabled5(stale_v);
0090     }
0091 #endif
0092     return SlowIsEnabled(stale_v, level);
0093   }
0094 
0095  private:
0096   friend int log_internal::RegisterAndInitialize(VLogSite* v);
0097   friend void log_internal::UpdateVLogSites();
0098   friend class log_internal::SyntheticBinary;
0099   static constexpr int kUninitialized = (std::numeric_limits<int>::max)();
0100 
0101   // SlowIsEnabled performs slower checks to determine whether a log site is
0102   // enabled. Because it is expected to be called somewhat rarely
0103   // (comparatively), it is not inlined to save on code size.
0104   //
0105   // Prerequisites to calling SlowIsEnabled:
0106   //   1) stale_v is uninitialized OR
0107   //   2) stale_v is initialized and >= level (meaning we must log).
0108   // Takes locks but does not allocate memory.
0109   ABSL_ATTRIBUTE_NOINLINE
0110   bool SlowIsEnabled(int stale_v, int level);
0111   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled0(int stale_v);
0112   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled1(int stale_v);
0113   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled2(int stale_v);
0114   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled3(int stale_v);
0115   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled4(int stale_v);
0116   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled5(int stale_v);
0117 
0118   // This object is too size-sensitive to use absl::string_view.
0119   const char* const file_;
0120   std::atomic<int> v_;
0121   std::atomic<VLogSite*> next_;
0122 };
0123 static_assert(std::is_trivially_destructible<VLogSite>::value,
0124               "VLogSite must be trivially destructible");
0125 
0126 // Returns the current verbose log level of `file`.
0127 // Does not allocate memory.
0128 int VLogLevel(absl::string_view file);
0129 
0130 // Registers a site `v` to get updated as `vmodule` and `v` change.  Also
0131 // initializes the site based on their current values, and returns that result.
0132 // Does not allocate memory.
0133 int RegisterAndInitialize(VLogSite* v);
0134 
0135 // Allocates memory.
0136 void UpdateVLogSites();
0137 
0138 // Completely overwrites the saved value of `vmodule`.
0139 // Allocates memory.
0140 void UpdateVModule(absl::string_view vmodule);
0141 
0142 // Updates the global verbosity level to `v` and returns the prior value.
0143 // Allocates memory.
0144 int UpdateGlobalVLogLevel(int v);
0145 
0146 // Atomically prepends `module_pattern=log_level` to the start of vmodule.
0147 // Returns the prior value for `module_pattern` if there was an exact match and
0148 // `global_v` otherwise.
0149 // Allocates memory.
0150 int PrependVModule(absl::string_view module_pattern, int log_level);
0151 
0152 // Registers `on_update` to be called whenever `v` or `vmodule` change.
0153 // Allocates memory.
0154 void OnVLogVerbosityUpdate(std::function<void()> cb);
0155 
0156 // Does not allocate memory.
0157 VLogSite* SetVModuleListHeadForTestOnly(VLogSite* v);
0158 
0159 }  // namespace log_internal
0160 ABSL_NAMESPACE_END
0161 }  // namespace absl
0162 
0163 #endif  // ABSL_LOG_INTERNAL_VLOG_CONFIG_H_