diff options
-rw-r--r-- | absl/algorithm/container.h | 3 | ||||
-rw-r--r-- | absl/base/BUILD.bazel | 2 | ||||
-rw-r--r-- | absl/base/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/base/internal/atomic_hook.h | 2 | ||||
-rw-r--r-- | absl/base/internal/raw_logging.cc | 4 | ||||
-rw-r--r-- | absl/base/internal/sysinfo.cc | 26 | ||||
-rw-r--r-- | absl/base/macros.h | 10 | ||||
-rw-r--r-- | absl/flags/flag.h | 8 | ||||
-rw-r--r-- | absl/flags/internal/flag.cc | 71 | ||||
-rw-r--r-- | absl/flags/internal/flag.h | 91 | ||||
-rw-r--r-- | absl/random/internal/BUILD.bazel | 2 | ||||
-rw-r--r-- | absl/random/internal/nanobenchmark.cc | 10 | ||||
-rw-r--r-- | absl/random/internal/randen_slow.cc | 10 | ||||
-rw-r--r-- | absl/random/internal/seed_material.cc | 12 | ||||
-rw-r--r-- | absl/strings/internal/str_format/bind.h | 2 | ||||
-rw-r--r-- | absl/strings/internal/str_format/checker.h | 9 | ||||
-rw-r--r-- | absl/strings/internal/str_format/checker_test.cc | 2 | ||||
-rw-r--r-- | absl/strings/internal/str_format/parser.h | 2 | ||||
-rw-r--r-- | absl/time/BUILD.bazel | 1 | ||||
-rw-r--r-- | absl/time/time_test.cc | 45 |
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"); |