about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--absl/algorithm/container.h3
-rw-r--r--absl/base/BUILD.bazel2
-rw-r--r--absl/base/CMakeLists.txt2
-rw-r--r--absl/base/internal/atomic_hook.h2
-rw-r--r--absl/base/internal/raw_logging.cc4
-rw-r--r--absl/base/internal/sysinfo.cc26
-rw-r--r--absl/base/macros.h10
-rw-r--r--absl/flags/flag.h8
-rw-r--r--absl/flags/internal/flag.cc71
-rw-r--r--absl/flags/internal/flag.h91
-rw-r--r--absl/random/internal/BUILD.bazel2
-rw-r--r--absl/random/internal/nanobenchmark.cc10
-rw-r--r--absl/random/internal/randen_slow.cc10
-rw-r--r--absl/random/internal/seed_material.cc12
-rw-r--r--absl/strings/internal/str_format/bind.h2
-rw-r--r--absl/strings/internal/str_format/checker.h9
-rw-r--r--absl/strings/internal/str_format/checker_test.cc2
-rw-r--r--absl/strings/internal/str_format/parser.h2
-rw-r--r--absl/time/BUILD.bazel1
-rw-r--r--absl/time/time_test.cc45
20 files changed, 200 insertions, 114 deletions
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index adcea8a79995..5dae9fd6a336 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -268,7 +268,8 @@ container_algorithm_internal::ContainerIter<Sequence1> c_find_end(
 // c_find_first_of()
 //
 // Container-based version of the <algorithm> `std::find_first_of()` function to
-// find the first elements in an ordered set within a container.
+// find the first element within the container that is also within the options
+// container.
 template <typename C1, typename C2>
 container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container,
                                                                 C2& options) {
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index f6b210f41e31..f8eb8aeb3b9c 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -193,7 +193,7 @@ cc_library(
     copts = ABSL_DEFAULT_COPTS,
     linkopts = select({
         "//absl:windows": [
-            "-DEFAULTLIB:shlwapi.lib",
+            "-DEFAULTLIB:advapi32.lib",
         ],
         "//conditions:default": ["-pthread"],
     }) + ABSL_DEFAULT_LINKOPTS,
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 9b0174d80efe..c521f32d1cab 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -176,7 +176,7 @@ absl_cc_library(
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
     $<$<BOOL:${LIBRT}>:${LIBRT}>
-    $<$<BOOL:${MINGW}>:"shlwapi">
+    $<$<BOOL:${MINGW}>:"advapi32">
   DEPS
     absl::atomic_hook
     absl::base_internal
diff --git a/absl/base/internal/atomic_hook.h b/absl/base/internal/atomic_hook.h
index 09f763d0742b..6df956a6ab66 100644
--- a/absl/base/internal/atomic_hook.h
+++ b/absl/base/internal/atomic_hook.h
@@ -63,7 +63,7 @@ class AtomicHook<ReturnType (*)(Args...)> {
   explicit constexpr AtomicHook(FnPtr default_fn)
       : hook_(default_fn), default_fn_(default_fn) {}
 #else
-  // On MSVC, this function sometimes executes after dynamic initiazliation =(.
+  // On MSVC, this function sometimes executes after dynamic initialization =(.
   // If a non-zero `hook_` has been installed by a dynamic initializer, we want
   // to preserve it.  If not, `hook_` will be zero initialized and we have no
   // need to set it to `kUninitialized`.
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index 878fe6c6c2cc..d20bf34ef538 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -37,9 +37,9 @@
 // this, consider moving both to config.h instead.
 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
     defined(__Fuchsia__) || defined(__native_client__) || \
-    defined(__EMSCRIPTEN__)
-#include <unistd.h>
+    defined(__EMSCRIPTEN__) || defined(__ASYLO__)
 
+#include <unistd.h>
 
 #define ABSL_HAVE_POSIX_WRITE 1
 #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc
index 93039bf23f13..68d4266b70cc 100644
--- a/absl/base/internal/sysinfo.cc
+++ b/absl/base/internal/sysinfo.cc
@@ -17,7 +17,6 @@
 #include "absl/base/attributes.h"
 
 #ifdef _WIN32
-#include <shlwapi.h>
 #include <windows.h>
 #else
 #include <fcntl.h>
@@ -76,14 +75,23 @@ static int GetNumCPUs() {
 #if defined(_WIN32)
 
 static double GetNominalCPUFrequency() {
-  DWORD data;
-  DWORD data_size = sizeof(data);
-  #pragma comment(lib, "shlwapi.lib")  // For SHGetValue().
-  if (SUCCEEDED(
-          SHGetValueA(HKEY_LOCAL_MACHINE,
-                      "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
-                      "~MHz", nullptr, &data, &data_size))) {
-    return data * 1e6;  // Value is MHz.
+#pragma comment(lib, "advapi32.lib")  // For Reg* functions.
+  HKEY key;
+  // Use the Reg* functions rather than the SH functions because shlwapi.dll
+  // pulls in gdi32.dll which makes process destruction much more costly.
+  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+                    "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
+                    KEY_READ, &key) == ERROR_SUCCESS) {
+    DWORD type = 0;
+    DWORD data = 0;
+    DWORD data_size = sizeof(data);
+    auto result = RegQueryValueExA(key, "~MHz", 0, &type,
+                                   reinterpret_cast<LPBYTE>(&data), &data_size);
+    RegCloseKey(key);
+    if (result == ERROR_SUCCESS && type == REG_DWORD &&
+        data_size == sizeof(data)) {
+      return data * 1e6;  // Value is MHz.
+    }
   }
   return 1.0;
 }
diff --git a/absl/base/macros.h b/absl/base/macros.h
index d481288f35f9..d414dcace38e 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -31,6 +31,7 @@
 #include <cassert>
 #include <cstddef>
 
+#include "absl/base/attributes.h"
 #include "absl/base/optimization.h"
 #include "absl/base/port.h"
 
@@ -176,12 +177,9 @@ enum LinkerInitialized {
 //     ABSL_BAD_CALL_IF(c <= -1 || c > 255,
 //                       "'c' must have the value of an unsigned char or EOF");
 //   #endif // ABSL_BAD_CALL_IF
-
-#if defined(__clang__)
-# if __has_attribute(enable_if)
-#  define ABSL_BAD_CALL_IF(expr, msg) \
-    __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg)))
-# endif
+#if ABSL_HAVE_ATTRIBUTE(enable_if)
+#define ABSL_BAD_CALL_IF(expr, msg) \
+  __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg)))
 #endif
 
 // ABSL_ASSERT()
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index 09af47a06d1b..52c3cede690a 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -96,12 +96,12 @@ class Flag {
   constexpr Flag(const char* name, const flags_internal::HelpGenFunc help_gen,
                  const char* filename,
                  const flags_internal::FlagMarshallingOpFn marshalling_op,
-                 const flags_internal::InitialValGenFunc initial_value_gen)
+                 const flags_internal::FlagDfltGenFunc default_value_gen)
       : name_(name),
         help_gen_(help_gen),
         filename_(filename),
         marshalling_op_(marshalling_op),
-        initial_value_gen_(initial_value_gen),
+        default_value_gen_(default_value_gen),
         inited_(false),
         impl_(nullptr) {}
 #endif
@@ -118,7 +118,7 @@ class Flag {
           name_,
           {flags_internal::FlagHelpSrc(help_gen_),
            flags_internal::FlagHelpSrcKind::kGenFunc},
-          filename_, marshalling_op_, initial_value_gen_);
+          filename_, marshalling_op_, default_value_gen_);
       inited_.store(true, std::memory_order_release);
     }
 
@@ -157,7 +157,7 @@ class Flag {
   const flags_internal::HelpGenFunc help_gen_;
   const char* filename_;
   const flags_internal::FlagMarshallingOpFn marshalling_op_;
-  const flags_internal::InitialValGenFunc initial_value_gen_;
+  const flags_internal::FlagDfltGenFunc default_value_gen_;
 
   mutable std::atomic<bool> inited_;
   mutable flags_internal::Flag<T>* impl_;
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc
index d087f79e891c..435cc362478f 100644
--- a/absl/flags/internal/flag.cc
+++ b/absl/flags/internal/flag.cc
@@ -49,12 +49,11 @@ void FlagImpl::Init() {
 
   absl::MutexLock lock(&locks_->primary_mu);
 
-  if (def_ != nullptr) {
+  if (cur_ != nullptr) {
     inited_.store(true, std::memory_order_release);
   } else {
-    // Need to initialize def and cur fields.
-    def_ = (*initial_value_gen_)();
-    cur_ = Clone(op_, def_);
+    // Need to initialize cur field.
+    cur_ = MakeInitValue().release();
     StoreAtomic();
     inited_.store(true, std::memory_order_release);
     InvokeCallback();
@@ -63,8 +62,7 @@ void FlagImpl::Init() {
 
 // Ensures that the lazily initialized data is initialized,
 // and returns pointer to the mutex guarding flags data.
-absl::Mutex* FlagImpl::DataGuard() const
-    ABSL_LOCK_RETURNED(locks_->primary_mu) {
+absl::Mutex* FlagImpl::DataGuard() const {
   if (ABSL_PREDICT_FALSE(!inited_.load(std::memory_order_acquire))) {
     const_cast<FlagImpl*>(this)->Init();
   }
@@ -79,12 +77,23 @@ void FlagImpl::Destroy() const {
 
     // Values are heap allocated for Abseil Flags.
     if (cur_) Delete(op_, cur_);
-    if (def_) Delete(op_, def_);
+    if (def_kind_ == FlagDefaultSrcKind::kDynamicValue)
+      Delete(op_, default_src_.dynamic_value);
   }
 
   delete locks_;
 }
 
+std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const {
+  void* res = nullptr;
+  if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) {
+    res = Clone(op_, default_src_.dynamic_value);
+  } else {
+    res = (*default_src_.gen_func)();
+  }
+  return {res, DynValueDeleter{op_}};
+}
+
 std::string FlagImpl::Help() const {
   return help_source_kind_ == FlagHelpSrcKind::kLiteral ? help_.literal
                                                         : help_.gen_func();
@@ -103,7 +112,8 @@ bool FlagImpl::IsSpecifiedOnCommandLine() const {
 std::string FlagImpl::DefaultValue() const {
   absl::MutexLock l(DataGuard());
 
-  return Unparse(marshalling_op_, def_);
+  auto obj = MakeInitValue();
+  return Unparse(marshalling_op_, obj.get());
 }
 
 std::string FlagImpl::CurrentValue() const {
@@ -121,8 +131,7 @@ void FlagImpl::SetCallback(
   InvokeCallback();
 }
 
-void FlagImpl::InvokeCallback() const
-    ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu) {
+void FlagImpl::InvokeCallback() const {
   if (!callback_) return;
 
   // If the flag has a mutation callback this function invokes it. While the
@@ -172,23 +181,20 @@ bool FlagImpl::RestoreState(const CommandLineFlag& flag, const void* value,
 // 'dst' assuming it is a pointer to the flag's value type. In case if any error
 // is encountered in either step, the error message is stored in 'err'
 bool FlagImpl::TryParse(const CommandLineFlag& flag, void* dst,
-                        absl::string_view value, std::string* err) const
-    ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu) {
-  void* tentative_value = Clone(op_, def_);
+                        absl::string_view value, std::string* err) const {
+  auto tentative_value = MakeInitValue();
   std::string parse_err;
-  if (!Parse(marshalling_op_, value, tentative_value, &parse_err)) {
+  if (!Parse(marshalling_op_, value, tentative_value.get(), &parse_err)) {
     auto type_name = flag.Typename();
     absl::string_view err_sep = parse_err.empty() ? "" : "; ";
     absl::string_view typename_sep = type_name.empty() ? "" : " ";
     *err = absl::StrCat("Illegal value '", value, "' specified for",
                         typename_sep, type_name, " flag '", flag.Name(), "'",
                         err_sep, parse_err);
-    Delete(op_, tentative_value);
     return false;
   }
 
-  Copy(op_, tentative_value, dst);
-  Delete(op_, tentative_value);
+  Copy(op_, tentative_value.get(), dst);
   return true;
 }
 
@@ -208,7 +214,7 @@ void FlagImpl::Read(const CommandLineFlag& flag, void* dst,
   CopyConstruct(op_, cur_, dst);
 }
 
-void FlagImpl::StoreAtomic() ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu) {
+void FlagImpl::StoreAtomic() {
   size_t data_size = Sizeof(op_);
 
   if (data_size <= sizeof(int64_t)) {
@@ -299,12 +305,22 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag,
       break;
     }
     case SET_FLAGS_DEFAULT: {
-      // modify the flag's default-value
-      if (!TryParse(flag, def_, value, err)) return false;
+      // Flag's new default-value.
+      auto new_default_value = MakeInitValue();
+
+      if (!TryParse(flag, new_default_value.get(), value, err)) return false;
+
+      if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) {
+        // Release old default value.
+        Delete(op_, default_src_.dynamic_value);
+      }
+
+      default_src_.dynamic_value = new_default_value.release();
+      def_kind_ = FlagDefaultSrcKind::kDynamicValue;
 
       if (!modified_) {
         // Need to set both default value *and* current, in this case
-        Copy(op_, def_, cur_);
+        Copy(op_, default_src_.dynamic_value, cur_);
         StoreAtomic();
         InvokeCallback();
       }
@@ -321,9 +337,9 @@ void FlagImpl::CheckDefaultValueParsingRoundtrip(
 
   absl::MutexLock lock(DataGuard());
 
-  void* dst = Clone(op_, def_);
+  auto dst = MakeInitValue();
   std::string error;
-  if (!flags_internal::Parse(marshalling_op_, v, dst, &error)) {
+  if (!flags_internal::Parse(marshalling_op_, v, dst.get(), &error)) {
     ABSL_INTERNAL_LOG(
         FATAL,
         absl::StrCat("Flag ", flag.Name(), " (from ", flag.Filename(),
@@ -333,18 +349,15 @@ void FlagImpl::CheckDefaultValueParsingRoundtrip(
 
   // We do not compare dst to def since parsing/unparsing may make
   // small changes, e.g., precision loss for floating point types.
-  Delete(op_, dst);
 }
 
 bool FlagImpl::ValidateInputValue(absl::string_view value) const {
   absl::MutexLock l(DataGuard());
 
-  void* obj = Clone(op_, def_);
+  auto obj = MakeInitValue();
   std::string ignored_error;
-  const bool result =
-      flags_internal::Parse(marshalling_op_, value, obj, &ignored_error);
-  Delete(op_, obj);
-  return result;
+  return flags_internal::Parse(marshalling_op_, value, obj.get(),
+                               &ignored_error);
 }
 
 }  // namespace flags_internal
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index d79902543a22..947a8cadaf2d 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -119,47 +119,61 @@ constexpr flags_internal::HelpInitArg HelpArg(char) {
           flags_internal::FlagHelpSrcKind::kGenFunc};
 }
 
-// Signature for the function generating the initial flag value based (usually
+// Signature for the function generating the initial flag value (usually
 // based on default value supplied in flag's definition)
-using InitialValGenFunc = void* (*)();
+using FlagDfltGenFunc = void* (*)();
+
+union FlagDefaultSrc {
+  constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg)
+      : gen_func(gen_func_arg) {}
+
+  void* dynamic_value;
+  FlagDfltGenFunc gen_func;
+};
+
+enum class FlagDefaultSrcKind : int8_t { kDynamicValue, kGenFunc };
 
 // Signature for the mutation callback used by watched Flags
 // The callback is noexcept.
 // TODO(rogeeff): add noexcept after C++17 support is added.
 using FlagCallback = void (*)();
 
-void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu,
-                    FlagCallback cb) ABSL_EXCLUSIVE_LOCKS_REQUIRED(primary_mu);
+struct DynValueDeleter {
+  void operator()(void* ptr) const { Delete(op, ptr); }
+
+  const FlagOpFn op;
+};
 
 // The class encapsulates the Flag's data and safe access to it.
 class FlagImpl {
  public:
   constexpr FlagImpl(const flags_internal::FlagOpFn op,
                      const flags_internal::FlagMarshallingOpFn marshalling_op,
-                     const flags_internal::InitialValGenFunc initial_value_gen,
+                     const flags_internal::FlagDfltGenFunc default_value_gen,
                      const HelpInitArg help)
       : op_(op),
         marshalling_op_(marshalling_op),
-        initial_value_gen_(initial_value_gen),
         help_(help.source),
-        help_source_kind_(help.kind) {}
+        help_source_kind_(help.kind),
+        def_kind_(flags_internal::FlagDefaultSrcKind::kGenFunc),
+        default_src_(default_value_gen) {}
 
   // Forces destruction of the Flag's data.
   void Destroy() const;
 
   // Constant access methods
   std::string Help() const;
-  bool IsModified() const ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
-  bool IsSpecifiedOnCommandLine() const ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
-  std::string DefaultValue() const ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
-  std::string CurrentValue() const ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+  bool IsModified() const ABSL_LOCKS_EXCLUDED(*DataGuard());
+  bool IsSpecifiedOnCommandLine() const ABSL_LOCKS_EXCLUDED(*DataGuard());
+  std::string DefaultValue() const ABSL_LOCKS_EXCLUDED(*DataGuard());
+  std::string CurrentValue() const ABSL_LOCKS_EXCLUDED(*DataGuard());
   void Read(const CommandLineFlag& flag, void* dst,
             const flags_internal::FlagOpFn dst_op) const
-      ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
   // Attempts to parse supplied `value` std::string.
   bool TryParse(const CommandLineFlag& flag, void* dst, absl::string_view value,
                 std::string* err) const
-      ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu);
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
   template <typename T>
   bool AtomicGet(T* v) const {
     const int64_t r = atomic_.load(std::memory_order_acquire);
@@ -174,23 +188,23 @@ class FlagImpl {
   // Mutating access methods
   void Write(const CommandLineFlag& flag, const void* src,
              const flags_internal::FlagOpFn src_op)
-      ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
   bool SetFromString(const CommandLineFlag& flag, absl::string_view value,
                      FlagSettingMode set_mode, ValueSource source,
-                     std::string* err) ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+                     std::string* err) ABSL_LOCKS_EXCLUDED(*DataGuard());
   // If possible, updates copy of the Flag's value that is stored in an
   // atomic word.
-  void StoreAtomic() ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu);
+  void StoreAtomic() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
 
   // Interfaces to operate on callbacks.
   void SetCallback(const flags_internal::FlagCallback mutation_callback)
-      ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
-  void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu);
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
+  void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
 
   // Interfaces to save/restore mutable flag data
   template <typename T>
   std::unique_ptr<flags_internal::FlagStateInterface> SaveState(
-      Flag<T>* flag) const ABSL_LOCKS_EXCLUDED(locks_->primary_mu) {
+      Flag<T>* flag) const ABSL_LOCKS_EXCLUDED(*DataGuard()) {
     T&& cur_value = flag->Get();
     absl::MutexLock l(DataGuard());
 
@@ -199,13 +213,13 @@ class FlagImpl {
   }
   bool RestoreState(const CommandLineFlag& flag, const void* value,
                     bool modified, bool on_command_line, int64_t counter)
-      ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
 
   // Value validation interfaces.
   void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag) const
-      ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
   bool ValidateInputValue(absl::string_view value) const
-      ABSL_LOCKS_EXCLUDED(locks_->primary_mu);
+      ABSL_LOCKS_EXCLUDED(*DataGuard());
 
  private:
   // Lazy initialization of the Flag's data.
@@ -214,27 +228,36 @@ class FlagImpl {
   // and returns pointer to the mutex guarding flags data.
   absl::Mutex* DataGuard() const ABSL_LOCK_RETURNED(locks_->primary_mu);
 
+  // Returns heap allocated value of type T initialized with default value.
+  std::unique_ptr<void, DynValueDeleter> MakeInitValue() const
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
+
   // Immutable Flag's data.
-  const FlagOpFn op_;                          // Type-specific handler.
-  const FlagMarshallingOpFn marshalling_op_;   // Marshalling ops handler.
-  const InitialValGenFunc initial_value_gen_;  // Makes flag's initial value.
+  const FlagOpFn op_;                         // Type-specific handler.
+  const FlagMarshallingOpFn marshalling_op_;  // Marshalling ops handler.
   const FlagHelpSrc help_;  // Help message literal or function to generate it.
   // Indicates if help message was supplied as literal or generator func.
   const FlagHelpSrcKind help_source_kind_;
 
-  // Mutable Flag's data. (guarded by locks_->primary_mu).
-  // Indicates that locks_, cur_ and def_ fields have been lazily initialized.
+  // Mutable Flag's data. (guarded by DataGuard()).
+  // Indicates that locks_ and cur_ fields have been lazily initialized.
   std::atomic<bool> inited_{false};
   // Has flag value been modified?
-  bool modified_ ABSL_GUARDED_BY(locks_->primary_mu) = false;
+  bool modified_ ABSL_GUARDED_BY(*DataGuard()) = false;
   // Specified on command line.
-  bool on_command_line_ ABSL_GUARDED_BY(locks_->primary_mu) = false;
-  // Lazily initialized pointer to default value
-  void* def_ ABSL_GUARDED_BY(locks_->primary_mu) = nullptr;
+  bool on_command_line_ ABSL_GUARDED_BY(*DataGuard()) = false;
+  // If def_kind_ == kDynamicValue, default_src_ holds a dynamically allocated
+  // value.
+  FlagDefaultSrcKind def_kind_ ABSL_GUARDED_BY(*DataGuard());
+  // Either a pointer to the function generating the default value based on the
+  // value specified in ABSL_FLAG or pointer to the dynamically set default
+  // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish
+  // these two cases.
+  FlagDefaultSrc default_src_ ABSL_GUARDED_BY(*DataGuard());
   // Lazily initialized pointer to current value
-  void* cur_ ABSL_GUARDED_BY(locks_->primary_mu) = nullptr;
+  void* cur_ ABSL_GUARDED_BY(*DataGuard()) = nullptr;
   // Mutation counter
-  int64_t counter_ ABSL_GUARDED_BY(locks_->primary_mu) = 0;
+  int64_t counter_ ABSL_GUARDED_BY(*DataGuard()) = 0;
   // For some types, a copy of the current value is kept in an atomically
   // accessible field.
   std::atomic<int64_t> atomic_{flags_internal::AtomicInit()};
@@ -263,7 +286,7 @@ class Flag final : public flags_internal::CommandLineFlag {
   constexpr Flag(const char* name, const flags_internal::HelpInitArg help,
                  const char* filename,
                  const flags_internal::FlagMarshallingOpFn marshalling_op,
-                 const flags_internal::InitialValGenFunc initial_value_gen)
+                 const flags_internal::FlagDfltGenFunc initial_value_gen)
       : flags_internal::CommandLineFlag(name, filename),
         impl_(&flags_internal::FlagOps<T>, marshalling_op, initial_value_gen,
               help) {}
diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel
index 5026e2b27220..952929ea264d 100644
--- a/absl/random/internal/BUILD.bazel
+++ b/absl/random/internal/BUILD.bazel
@@ -297,6 +297,7 @@ cc_library(
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":platform",
+        "//absl/base:core_headers",
     ],
 )
 
@@ -659,6 +660,7 @@ cc_library(
     deps = [
         ":platform",
         ":randen_engine",
+        "//absl/base:core_headers",
         "//absl/base:raw_logging_internal",
     ],
 )
diff --git a/absl/random/internal/nanobenchmark.cc b/absl/random/internal/nanobenchmark.cc
index 7f37800c6830..feb81c859585 100644
--- a/absl/random/internal/nanobenchmark.cc
+++ b/absl/random/internal/nanobenchmark.cc
@@ -27,6 +27,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/base/attributes.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/random/internal/platform.h"
 #include "absl/random/internal/randen_engine.h"
@@ -59,15 +60,6 @@
 #include <time.h>  // NOLINT
 #endif
 
-// ABSL_HAVE_ATTRIBUTE
-#if !defined(ABSL_HAVE_ATTRIBUTE)
-#ifdef __has_attribute
-#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x)
-#else
-#define ABSL_HAVE_ATTRIBUTE(x) 0
-#endif
-#endif
-
 // ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE prevents inlining of the method.
 #if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__))
 #define ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE __attribute__((noinline))
diff --git a/absl/random/internal/randen_slow.cc b/absl/random/internal/randen_slow.cc
index 7a2e2daa53f5..e7959c7e0525 100644
--- a/absl/random/internal/randen_slow.cc
+++ b/absl/random/internal/randen_slow.cc
@@ -18,17 +18,9 @@
 #include <cstdint>
 #include <cstring>
 
+#include "absl/base/attributes.h"
 #include "absl/random/internal/platform.h"
 
-// ABSL_HAVE_ATTRIBUTE
-#if !defined(ABSL_HAVE_ATTRIBUTE)
-#ifdef __has_attribute
-#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x)
-#else
-#define ABSL_HAVE_ATTRIBUTE(x) 0
-#endif
-#endif
-
 #if ABSL_HAVE_ATTRIBUTE(always_inline) || \
     (defined(__GNUC__) && !defined(__clang__))
 #define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE \
diff --git a/absl/random/internal/seed_material.cc b/absl/random/internal/seed_material.cc
index 85dd535f9c09..ab4dd0c26b07 100644
--- a/absl/random/internal/seed_material.cc
+++ b/absl/random/internal/seed_material.cc
@@ -45,6 +45,9 @@
 #define ABSL_RANDOM_USE_BCRYPT 1
 #pragma comment(lib, "bcrypt.lib")
 
+#elif defined(__Fuchsia__)
+#include <zircon/syscalls.h>
+
 #endif
 
 #if defined(ABSL_RANDOM_USE_BCRYPT)
@@ -107,6 +110,15 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
   return true;
 }
 
+#elif defined(__Fuchsia__)
+
+bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
+  auto buffer = reinterpret_cast<uint8_t*>(values.data());
+  size_t buffer_size = sizeof(uint32_t) * values.size();
+  zx_cprng_draw(buffer, buffer_size);
+  return true;
+}
+
 #else
 
 // On *nix, read entropy from /dev/urandom.
diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h
index 7f46035113bb..dafcd6102f91 100644
--- a/absl/strings/internal/str_format/bind.h
+++ b/absl/strings/internal/str_format/bind.h
@@ -73,7 +73,7 @@ class FormatSpecTemplate
   using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type;
 
  public:
-#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
+#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
 
   // Honeypot overload for when the std::string is not constexpr.
   // We use the 'unavailable' attribute to give a better compiler error than
diff --git a/absl/strings/internal/str_format/checker.h b/absl/strings/internal/str_format/checker.h
index 8b594f2d5cc6..04a888275185 100644
--- a/absl/strings/internal/str_format/checker.h
+++ b/absl/strings/internal/str_format/checker.h
@@ -1,17 +1,16 @@
 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
 
+#include "absl/base/attributes.h"
 #include "absl/strings/internal/str_format/arg.h"
 #include "absl/strings/internal/str_format/extension.h"
 
 // Compile time check support for entry points.
 
 #ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
-#if defined(__clang__) && !defined(__native_client__)
-#if __has_attribute(enable_if)
+#if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__)
 #define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1
-#endif  // __has_attribute(enable_if)
-#endif  // defined(__clang__) && !defined(__native_client__)
+#endif  // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__)
 #endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
 
 namespace absl {
@@ -31,7 +30,7 @@ constexpr Conv ArgumentToConv() {
       std::declval<FormatSinkImpl*>()))::kConv;
 }
 
-#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
+#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
 
 constexpr bool ContainsChar(const char* chars, char c) {
   return *chars == c || (*chars && ContainsChar(chars + 1, c));
diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc
index c1d8c769ef7d..7aa194a7fa90 100644
--- a/absl/strings/internal/str_format/checker_test.cc
+++ b/absl/strings/internal/str_format/checker_test.cc
@@ -35,7 +35,7 @@ TEST(StrFormatChecker, ArgumentToConv) {
   EXPECT_EQ(ConvToString(conv), "p");
 }
 
-#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
+#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
 
 struct Case {
   bool result;
diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h
index b7614a09fa4e..4b441f7193a5 100644
--- a/absl/strings/internal/str_format/parser.h
+++ b/absl/strings/internal/str_format/parser.h
@@ -274,7 +274,7 @@ template <str_format_internal::Conv... C>
 class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase {
  public:
   explicit ExtendedParsedFormat(string_view format)
-#if ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
+#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
       __attribute__((
           enable_if(str_format_internal::EnsureConstexpr(format),
                     "Format std::string is not constexpr."),
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel
index a615152f01ba..9ab2adb88666 100644
--- a/absl/time/BUILD.bazel
+++ b/absl/time/BUILD.bazel
@@ -93,6 +93,7 @@ cc_test(
         ":time",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/numeric:int128",
         "//absl/time/internal/cctz:time_zone",
         "@com_google_googletest//:gtest_main",
     ],
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 9c4709e6b469..6f89672c66d6 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -27,6 +27,7 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include "absl/numeric/int128.h"
 #include "absl/time/clock.h"
 #include "absl/time/internal/test_util.h"
 
@@ -575,6 +576,50 @@ TEST(Time, ToChronoTime) {
             absl::ToChronoTime(absl::UnixEpoch() - tick));
 }
 
+// Check that absl::int128 works as a std::chrono::duration representation.
+TEST(Time, Chrono128) {
+  // Define a std::chrono::time_point type whose time[sic]_since_epoch() is
+  // a signed 128-bit count of attoseconds. This has a range and resolution
+  // (currently) beyond those of absl::Time, and undoubtedly also beyond those
+  // of std::chrono::system_clock::time_point.
+  //
+  // Note: The to/from-chrono support should probably be updated to handle
+  // such wide representations.
+  using Timestamp =
+      std::chrono::time_point<std::chrono::system_clock,
+                              std::chrono::duration<absl::int128, std::atto>>;
+
+  // Expect that we can round-trip the std::chrono::system_clock::time_point
+  // extremes through both absl::Time and Timestamp, and that Timestamp can
+  // handle the (current) absl::Time extremes.
+  //
+  // Note: We should use std::chrono::floor() instead of time_point_cast(),
+  // but floor() is only available since c++17.
+  for (const auto tp : {std::chrono::system_clock::time_point::min(),
+                        std::chrono::system_clock::time_point::max()}) {
+    EXPECT_EQ(tp, absl::ToChronoTime(absl::FromChrono(tp)));
+    EXPECT_EQ(tp, std::chrono::time_point_cast<
+                      std::chrono::system_clock::time_point::duration>(
+                      std::chrono::time_point_cast<Timestamp::duration>(tp)));
+  }
+  Timestamp::duration::rep v = std::numeric_limits<int64_t>::min();
+  v *= Timestamp::duration::period::den;
+  auto ts = Timestamp(Timestamp::duration(v));
+  ts += std::chrono::duration<int64_t, std::atto>(0);
+  EXPECT_EQ(std::numeric_limits<int64_t>::min(),
+            ts.time_since_epoch().count() / Timestamp::duration::period::den);
+  EXPECT_EQ(0,
+            ts.time_since_epoch().count() % Timestamp::duration::period::den);
+  v = std::numeric_limits<int64_t>::max();
+  v *= Timestamp::duration::period::den;
+  ts = Timestamp(Timestamp::duration(v));
+  ts += std::chrono::duration<int64_t, std::atto>(999999999750000000);
+  EXPECT_EQ(std::numeric_limits<int64_t>::max(),
+            ts.time_since_epoch().count() / Timestamp::duration::period::den);
+  EXPECT_EQ(999999999750000000,
+            ts.time_since_epoch().count() % Timestamp::duration::period::den);
+}
+
 TEST(Time, TimeZoneAt) {
   const absl::TimeZone nyc =
       absl::time_internal::LoadTimeZone("America/New_York");