Commit 322ae242 by Abseil Team Committed by Andy Getz

Export of internal Abseil changes

--
1609589925459c2c0b2a17912c0d65227f709db9 by Abseil Team <absl-team@google.com>:

Clarify the "Potential Mutex deadlock" reason message.

PiperOrigin-RevId: 351367862

--
88bf28863db2c2d2d48767c3e4dfab6a48bdff79 by Abseil Team <absl-team@google.com>:

Print CPU number is fault handler.

This CL adds code to print CPU number inside the fault handler.  This is only supported on Linux.  The CPU number is also a hint only.  There is no guarantee that it is indeed the CPU on which a fault happened.

PiperOrigin-RevId: 351238373

--
66a9c8e44b5744fec1ca0d7b8db7e1d50772d9a2 by Samuel Benzaquen <sbenza@google.com>:

Add better error message for ODR violations of flags.

PiperOrigin-RevId: 351197423

--
6efd1efb341563148dd43255aaa4bf959dfd9554 by Chris Kennelly <ckennelly@google.com>:

Assume bitwise builtins are available on GCC.

These are long-standing builtins but are not consistently detected by
ABSL_HAVE_BUILTIN.

PiperOrigin-RevId: 350814036
GitOrigin-RevId: 1609589925459c2c0b2a17912c0d65227f709db9
Change-Id: Ied3fd2f135187f2c316b403fba45f3bbaea54138
parent 62ce712e
...@@ -379,6 +379,15 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || ...@@ -379,6 +379,15 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 #define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1
#endif #endif
// ABSL_HAVE_SCHED_GETCPU
//
// Checks whether sched_getcpu is available.
#ifdef ABSL_HAVE_SCHED_GETCPU
#error ABSL_HAVE_SCHED_GETCPU cannot be directly set
#elif defined(__linux__)
#define ABSL_HAVE_SCHED_GETCPU 1
#endif
// ABSL_HAVE_SCHED_YIELD // ABSL_HAVE_SCHED_YIELD
// //
// Checks whether the platform implements sched_yield(2) as defined in // Checks whether the platform implements sched_yield(2) as defined in
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
#include <sched.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
...@@ -219,17 +220,24 @@ static void WriteToStderr(const char* data) { ...@@ -219,17 +220,24 @@ static void WriteToStderr(const char* data) {
absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data)); absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data));
} }
static void WriteSignalMessage(int signo, void (*writerfn)(const char*)) { static void WriteSignalMessage(int signo, int cpu,
char buf[64]; void (*writerfn)(const char*)) {
char buf[96];
char on_cpu[32] = {0};
if (cpu != -1) {
snprintf(on_cpu, sizeof(on_cpu), " on cpu %d", cpu);
}
const char* const signal_string = const char* const signal_string =
debugging_internal::FailureSignalToString(signo); debugging_internal::FailureSignalToString(signo);
if (signal_string != nullptr && signal_string[0] != '\0') { if (signal_string != nullptr && signal_string[0] != '\0') {
snprintf(buf, sizeof(buf), "*** %s received at time=%ld ***\n", snprintf(buf, sizeof(buf), "*** %s received at time=%ld%s ***\n",
signal_string, signal_string,
static_cast<long>(time(nullptr))); // NOLINT(runtime/int) static_cast<long>(time(nullptr)), // NOLINT(runtime/int)
on_cpu);
} else { } else {
snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld ***\n", snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld%s ***\n",
signo, static_cast<long>(time(nullptr))); // NOLINT(runtime/int) signo, static_cast<long>(time(nullptr)), // NOLINT(runtime/int)
on_cpu);
} }
writerfn(buf); writerfn(buf);
} }
...@@ -269,10 +277,10 @@ ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace( ...@@ -269,10 +277,10 @@ ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace(
// Called by AbslFailureSignalHandler() to write the failure info. It is // Called by AbslFailureSignalHandler() to write the failure info. It is
// called once with writerfn set to WriteToStderr() and then possibly // called once with writerfn set to WriteToStderr() and then possibly
// with writerfn set to the user provided function. // with writerfn set to the user provided function.
static void WriteFailureInfo(int signo, void* ucontext, static void WriteFailureInfo(int signo, void* ucontext, int cpu,
void (*writerfn)(const char*)) { void (*writerfn)(const char*)) {
WriterFnStruct writerfn_struct{writerfn}; WriterFnStruct writerfn_struct{writerfn};
WriteSignalMessage(signo, writerfn); WriteSignalMessage(signo, cpu, writerfn);
WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper, WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper,
&writerfn_struct); &writerfn_struct);
} }
...@@ -334,6 +342,14 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { ...@@ -334,6 +342,14 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
} }
} }
// Increase the chance that the CPU we report was the same CPU on which the
// signal was received by doing this as early as possible, i.e. after
// verifying that this is not a recursive signal handler invocation.
int my_cpu = -1;
#ifdef ABSL_HAVE_SCHED_GETCPU
my_cpu = sched_getcpu();
#endif
#ifdef ABSL_HAVE_ALARM #ifdef ABSL_HAVE_ALARM
// Set an alarm to abort the program in case this code hangs or deadlocks. // Set an alarm to abort the program in case this code hangs or deadlocks.
if (fsh_options.alarm_on_failure_secs > 0) { if (fsh_options.alarm_on_failure_secs > 0) {
...@@ -344,12 +360,12 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { ...@@ -344,12 +360,12 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
#endif #endif
// First write to stderr. // First write to stderr.
WriteFailureInfo(signo, ucontext, WriteToStderr); WriteFailureInfo(signo, ucontext, my_cpu, WriteToStderr);
// Riskier code (because it is less likely to be async-signal-safe) // Riskier code (because it is less likely to be async-signal-safe)
// goes after this point. // goes after this point.
if (fsh_options.writerfn != nullptr) { if (fsh_options.writerfn != nullptr) {
WriteFailureInfo(signo, ucontext, fsh_options.writerfn); WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn);
} }
if (fsh_options.call_previous_handler) { if (fsh_options.call_previous_handler) {
......
...@@ -122,6 +122,12 @@ TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) { ...@@ -122,6 +122,12 @@ TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) {
"*** ", absl::debugging_internal::FailureSignalToString(signo), "*** ", absl::debugging_internal::FailureSignalToString(signo),
" received at "))); " received at ")));
// On platforms where it is possible to get the current CPU, the
// CPU number is also logged. Check that it is present in output.
#if defined(__linux__)
EXPECT_THAT(error_line, testing::HasSubstr(" on cpu "));
#endif
if (absl::debugging_internal::StackTraceWorksForTest()) { if (absl::debugging_internal::StackTraceWorksForTest()) {
std::getline(error_output, error_line); std::getline(error_output, error_line);
EXPECT_THAT(error_line, StartsWith("PC: ")); EXPECT_THAT(error_line, StartsWith("PC: "));
......
...@@ -302,12 +302,14 @@ ABSL_NAMESPACE_END ...@@ -302,12 +302,14 @@ ABSL_NAMESPACE_END
#define ABSL_FLAG_IMPL_FLAGNAME(txt) "" #define ABSL_FLAG_IMPL_FLAGNAME(txt) ""
#define ABSL_FLAG_IMPL_FILENAME() "" #define ABSL_FLAG_IMPL_FILENAME() ""
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ #define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
absl::flags_internal::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(flag)) absl::flags_internal::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \
nullptr)
#else #else
#define ABSL_FLAG_IMPL_FLAGNAME(txt) txt #define ABSL_FLAG_IMPL_FLAGNAME(txt) txt
#define ABSL_FLAG_IMPL_FILENAME() __FILE__ #define ABSL_FLAG_IMPL_FILENAME() __FILE__
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ #define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
absl::flags_internal::FlagRegistrar<T, true>(ABSL_FLAG_IMPL_FLAG_PTR(flag)) absl::flags_internal::FlagRegistrar<T, true>(ABSL_FLAG_IMPL_FLAG_PTR(flag), \
__FILE__)
#endif #endif
// ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_HELP // ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_HELP
......
...@@ -177,7 +177,7 @@ bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) { ...@@ -177,7 +177,7 @@ bool TestConstructionFor(const absl::Flag<T>& f1, absl::Flag<T>& f2) {
EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help"); EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help");
EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file"); EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file");
flags::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(f2)) flags::FlagRegistrar<T, false>(ABSL_FLAG_IMPL_FLAG_PTR(f2), nullptr)
.OnUpdate(TestCallback); .OnUpdate(TestCallback);
EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2"); EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2");
......
...@@ -721,8 +721,9 @@ struct FlagRegistrarEmpty {}; ...@@ -721,8 +721,9 @@ struct FlagRegistrarEmpty {};
template <typename T, bool do_register> template <typename T, bool do_register>
class FlagRegistrar { class FlagRegistrar {
public: public:
explicit FlagRegistrar(Flag<T>& flag) : flag_(flag) { explicit FlagRegistrar(Flag<T>& flag, const char* filename) : flag_(flag) {
if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_); if (do_register)
flags_internal::RegisterCommandLineFlag(flag_.impl_, filename);
} }
FlagRegistrar OnUpdate(FlagCallbackFunc cb) && { FlagRegistrar OnUpdate(FlagCallbackFunc cb) && {
......
...@@ -36,7 +36,7 @@ void ForEachFlag(std::function<void(CommandLineFlag&)> visitor); ...@@ -36,7 +36,7 @@ void ForEachFlag(std::function<void(CommandLineFlag&)> visitor);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool RegisterCommandLineFlag(CommandLineFlag&); bool RegisterCommandLineFlag(CommandLineFlag&, const char* filename);
void FinalizeRegistry(); void FinalizeRegistry();
......
...@@ -50,7 +50,7 @@ class FlagRegistry { ...@@ -50,7 +50,7 @@ class FlagRegistry {
~FlagRegistry() = default; ~FlagRegistry() = default;
// Store a flag in this registry. Takes ownership of *flag. // Store a flag in this registry. Takes ownership of *flag.
void RegisterFlag(CommandLineFlag& flag); void RegisterFlag(CommandLineFlag& flag, const char* filename);
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); }
void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); }
...@@ -110,7 +110,20 @@ CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) { ...@@ -110,7 +110,20 @@ CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) {
return it != flags_.end() ? it->second : nullptr; return it != flags_.end() ? it->second : nullptr;
} }
void FlagRegistry::RegisterFlag(CommandLineFlag& flag) { void FlagRegistry::RegisterFlag(CommandLineFlag& flag, const char* filename) {
if (filename != nullptr &&
flag.Filename() != GetUsageConfig().normalize_filename(filename)) {
flags_internal::ReportUsageError(
absl::StrCat(
"Inconsistency between flag object and registration for flag '",
flag.Name(),
"', likely due to duplicate flags or an ODR violation. Relevant "
"files: ",
flag.Filename(), " and ", filename),
true);
std::exit(1);
}
FlagRegistryLock registry_lock(*this); FlagRegistryLock registry_lock(*this);
std::pair<FlagIterator, bool> ins = std::pair<FlagIterator, bool> ins =
...@@ -175,8 +188,8 @@ void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) { ...@@ -175,8 +188,8 @@ void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
bool RegisterCommandLineFlag(CommandLineFlag& flag) { bool RegisterCommandLineFlag(CommandLineFlag& flag, const char* filename) {
FlagRegistry::GlobalRegistry().RegisterFlag(flag); FlagRegistry::GlobalRegistry().RegisterFlag(flag, filename);
return true; return true;
} }
...@@ -266,7 +279,7 @@ void Retire(const char* name, FlagFastTypeId type_id, char* buf) { ...@@ -266,7 +279,7 @@ void Retire(const char* name, FlagFastTypeId type_id, char* buf) {
static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, ""); static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, "");
auto* flag = ::new (static_cast<void*>(buf)) auto* flag = ::new (static_cast<void*>(buf))
flags_internal::RetiredFlagObj(name, type_id); flags_internal::RetiredFlagObj(name, type_id);
FlagRegistry::GlobalRegistry().RegisterFlag(*flag); FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr);
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -560,6 +560,14 @@ TEST(IntegralPowersOfTwo, Width) { ...@@ -560,6 +560,14 @@ TEST(IntegralPowersOfTwo, Width) {
} }
} }
// On GCC and Clang, anticiapte that implementations will be constexpr
#if defined(__GNUC__)
static_assert(ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT,
"popcount should be constexpr");
static_assert(ABSL_INTERNAL_HAS_CONSTEXPR_CLZ, "clz should be constexpr");
static_assert(ABSL_INTERNAL_HAS_CONSTEXPR_CTZ, "ctz should be constexpr");
#endif
} // namespace } // namespace
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
...@@ -28,8 +28,15 @@ ...@@ -28,8 +28,15 @@
#include "absl/base/attributes.h" #include "absl/base/attributes.h"
#include "absl/base/config.h" #include "absl/base/config.h"
#if ABSL_HAVE_BUILTIN(__builtin_popcountl) && \ #if defined(__GNUC__) && !defined(__clang__)
ABSL_HAVE_BUILTIN(__builtin_popcountll) // GCC
#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) 1
#else
#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) ABSL_HAVE_BUILTIN(x)
#endif
#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountl) && \
ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll)
#define ABSL_INTERNAL_CONSTEXPR_POPCOUNT constexpr #define ABSL_INTERNAL_CONSTEXPR_POPCOUNT constexpr
#define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 1 #define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 1
#else #else
...@@ -37,7 +44,8 @@ ...@@ -37,7 +44,8 @@
#define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 0 #define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 0
#endif #endif
#if ABSL_HAVE_BUILTIN(__builtin_clz) && ABSL_HAVE_BUILTIN(__builtin_clzll) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) && \
ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll)
#define ABSL_INTERNAL_CONSTEXPR_CLZ constexpr #define ABSL_INTERNAL_CONSTEXPR_CLZ constexpr
#define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 1 #define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 1
#else #else
...@@ -45,7 +53,8 @@ ...@@ -45,7 +53,8 @@
#define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 0 #define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 0
#endif #endif
#if ABSL_HAVE_BUILTIN(__builtin_ctz) && ABSL_HAVE_BUILTIN(__builtin_ctzll) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) && \
ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll)
#define ABSL_INTERNAL_CONSTEXPR_CTZ constexpr #define ABSL_INTERNAL_CONSTEXPR_CTZ constexpr
#define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 1 #define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 1
#else #else
...@@ -85,7 +94,7 @@ ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft( ...@@ -85,7 +94,7 @@ ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft(
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount32(uint32_t x) noexcept { Popcount32(uint32_t x) noexcept {
#if ABSL_HAVE_BUILTIN(__builtin_popcount) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcount)
static_assert(sizeof(unsigned int) == sizeof(x), static_assert(sizeof(unsigned int) == sizeof(x),
"__builtin_popcount does not take 32-bit arg"); "__builtin_popcount does not take 32-bit arg");
return __builtin_popcount(x); return __builtin_popcount(x);
...@@ -98,7 +107,7 @@ Popcount32(uint32_t x) noexcept { ...@@ -98,7 +107,7 @@ Popcount32(uint32_t x) noexcept {
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount64(uint64_t x) noexcept { Popcount64(uint64_t x) noexcept {
#if ABSL_HAVE_BUILTIN(__builtin_popcountll) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll)
static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int)
"__builtin_popcount does not take 64-bit arg"); "__builtin_popcount does not take 64-bit arg");
return __builtin_popcountll(x); return __builtin_popcountll(x);
...@@ -122,7 +131,7 @@ Popcount(T x) noexcept { ...@@ -122,7 +131,7 @@ Popcount(T x) noexcept {
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes32(uint32_t x) { CountLeadingZeroes32(uint32_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_clz) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz)
// Use __builtin_clz, which uses the following instructions: // Use __builtin_clz, which uses the following instructions:
// x86: bsr, lzcnt // x86: bsr, lzcnt
// ARM64: clz // ARM64: clz
...@@ -169,7 +178,7 @@ CountLeadingZeroes16(uint16_t x) { ...@@ -169,7 +178,7 @@ CountLeadingZeroes16(uint16_t x) {
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes64(uint64_t x) { CountLeadingZeroes64(uint64_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_clzll) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll)
// Use __builtin_clzll, which uses the following instructions: // Use __builtin_clzll, which uses the following instructions:
// x86: bsr, lzcnt // x86: bsr, lzcnt
// ARM64: clz // ARM64: clz
...@@ -240,7 +249,7 @@ CountLeadingZeroes(T x) { ...@@ -240,7 +249,7 @@ CountLeadingZeroes(T x) {
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero32(uint32_t x) { CountTrailingZeroesNonzero32(uint32_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_ctz) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz)
static_assert(sizeof(unsigned int) == sizeof(x), static_assert(sizeof(unsigned int) == sizeof(x),
"__builtin_ctz does not take 32-bit arg"); "__builtin_ctz does not take 32-bit arg");
return __builtin_ctz(x); return __builtin_ctz(x);
...@@ -262,7 +271,7 @@ CountTrailingZeroesNonzero32(uint32_t x) { ...@@ -262,7 +271,7 @@ CountTrailingZeroesNonzero32(uint32_t x) {
ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero64(uint64_t x) { CountTrailingZeroesNonzero64(uint64_t x) {
#if ABSL_HAVE_BUILTIN(__builtin_ctzll) #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll)
static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int)
"__builtin_ctzll does not take 64-bit arg"); "__builtin_ctzll does not take 64-bit arg");
return __builtin_ctzll(x); return __builtin_ctzll(x);
......
...@@ -1372,7 +1372,9 @@ static GraphId DeadlockCheck(Mutex *mu) { ...@@ -1372,7 +1372,9 @@ static GraphId DeadlockCheck(Mutex *mu) {
len += static_cast<int>(strlen(&b->buf[len])); len += static_cast<int>(strlen(&b->buf[len]));
} }
} }
ABSL_RAW_LOG(ERROR, "Acquiring %p Mutexes held: %s", ABSL_RAW_LOG(ERROR,
"Acquiring absl::Mutex %p while holding %s; a cycle in the "
"historical lock ordering graph has been observed",
static_cast<void *>(mu), b->buf); static_cast<void *>(mu), b->buf);
ABSL_RAW_LOG(ERROR, "Cycle: "); ABSL_RAW_LOG(ERROR, "Cycle: ");
int path_len = deadlock_graph->FindPath( int path_len = deadlock_graph->FindPath(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment