Commit 55c04eb9 by Abseil Team Committed by vslashg

Export of internal Abseil changes

--
69b3ab092ee0fef3d27f589e709280c341f006c6 by Greg Falcon <gfalcon@google.com>:

Import of CCTZ from GitHub.

PiperOrigin-RevId: 321005878

--
3a4038cd0cea6455453a7ae82f2de7e91d7e2bc1 by Abseil Team <absl-team@google.com>:

Google-internal changes only.

PiperOrigin-RevId: 320994821

--
f9d9a93782924df6ffc351a271c239ca4bdff3c8 by Derek Mauro <dmauro@google.com>:

Update Linux latest toolchains, most notably to GCC 10.1

This create a new "hybrid" docker image that includes the latest
versions of both GCC and LLVM. Since the LLVM build targets Debian 10,
but Debian 10 uses an older version of libstdc++ that doesn't have
full C++20 support, the easiest solution is to use the GCC/Debian 10
base image from DockerHub and copy LLVM into it.

This also includes fixes to get the build working with the
new toolchains.

PiperOrigin-RevId: 320991795

--
43129cd66dc4439b36d85030800a3929f20d9f86 by Abseil Team <absl-team@google.com>:

Rollback import of CCTZ from GitHub (breaks MSAN tests)

  - e87b391f0d10ae9c3d2e70e4a3633337d2c5e643 handle "slim" TZif files in TimeZoneInfo::ExtendTransitio... by Bradley White <14679271+devbww@users.noreply.github.com>

PiperOrigin-RevId: 320978767

--
2a343a55f297d433c1521920f0bd20ddd2dc71e8 by Derek Mauro <dmauro@google.com>:

Use ABSL_HAVE_ATTRIBUTE in thread_annotations.h

PiperOrigin-RevId: 320956378

--
f6f3e8333c9ef6e6441586be6587bbfb1c8c8127 by Gennadiy Rozental <rogeeff@google.com>:

Import of CCTZ from GitHub.

PiperOrigin-RevId: 320952592

--
3cc2bcce3533ac1233c0536232b07eea45fe8ed0 by Derek Mauro <dmauro@google.com>:

Internal change

PiperOrigin-RevId: 320862698

--
4e22066476744609e42c475b55e3cbd874f04c39 by Gennadiy Rozental <rogeeff@google.com>:

Internal change

PiperOrigin-RevId: 320461277
GitOrigin-RevId: 69b3ab092ee0fef3d27f589e709280c341f006c6
Change-Id: I36f547711e7078d52f2e0a1ff3f4c903056a2b9e
parent 302b250e
...@@ -20,9 +20,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") ...@@ -20,9 +20,9 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# GoogleTest/GoogleMock framework. Used by most unit-tests. # GoogleTest/GoogleMock framework. Used by most unit-tests.
http_archive( http_archive(
name = "com_google_googletest", name = "com_google_googletest",
urls = ["https://github.com/google/googletest/archive/011959aafddcd30611003de96cfd8d7a7685c700.zip"], # 2020-05-14T00:36:05Z urls = ["https://github.com/google/googletest/archive/8567b09290fe402cf01923e2131c5635b8ed851b.zip"], # 2020-06-12T22:24:28Z
strip_prefix = "googletest-011959aafddcd30611003de96cfd8d7a7685c700", strip_prefix = "googletest-8567b09290fe402cf01923e2131c5635b8ed851b",
sha256 = "6a5d7d63cd6e0ad2a7130471105a3b83799a7a2b14ef7ec8d742b54f01a4833c", sha256 = "9a8a166eb6a56c7b3d7b19dc2c946fe4778fd6f21c7a12368ad3b836d8f1be48",
) )
# Google benchmark. # Google benchmark.
......
...@@ -61,5 +61,8 @@ config_setting( ...@@ -61,5 +61,8 @@ config_setting(
config_setting( config_setting(
name = "wasm", name = "wasm",
values = {"cpu": "wasm32"}, values = {
"cpu": "wasm32",
},
visibility = [":__subpackages__"],
) )
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
#define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ #define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/scheduling_mode.h" #include "absl/base/internal/scheduling_mode.h"
#include "absl/base/macros.h" #include "absl/base/macros.h"
...@@ -29,6 +30,13 @@ extern "C" void __google_enable_rescheduling(bool disable_result); ...@@ -29,6 +30,13 @@ extern "C" void __google_enable_rescheduling(bool disable_result);
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
class CondVar;
class Mutex;
namespace synchronization_internal {
int MutexDelay(int32_t c, int mode);
} // namespace synchronization_internal
namespace base_internal { namespace base_internal {
class SchedulingHelper; // To allow use of SchedulingGuard. class SchedulingHelper; // To allow use of SchedulingGuard.
...@@ -76,9 +84,23 @@ class SchedulingGuard { ...@@ -76,9 +84,23 @@ class SchedulingGuard {
bool disabled; bool disabled;
}; };
// A scoped helper to enable rescheduling temporarily.
// REQUIRES: destructor must run in same thread as constructor.
class ScopedEnable {
public:
ScopedEnable();
~ScopedEnable();
private:
int scheduling_disabled_depth_;
};
// Access to SchedulingGuard is explicitly permitted. // Access to SchedulingGuard is explicitly permitted.
friend class absl::CondVar;
friend class absl::Mutex;
friend class SchedulingHelper; friend class SchedulingHelper;
friend class SpinLock; friend class SpinLock;
friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode);
SchedulingGuard(const SchedulingGuard&) = delete; SchedulingGuard(const SchedulingGuard&) = delete;
SchedulingGuard& operator=(const SchedulingGuard&) = delete; SchedulingGuard& operator=(const SchedulingGuard&) = delete;
...@@ -100,6 +122,12 @@ inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) { ...@@ -100,6 +122,12 @@ inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) {
return; return;
} }
inline SchedulingGuard::ScopedEnable::ScopedEnable()
: scheduling_disabled_depth_(0) {}
inline SchedulingGuard::ScopedEnable::~ScopedEnable() {
ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning");
}
} // namespace base_internal } // namespace base_internal
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
......
...@@ -39,12 +39,6 @@ ...@@ -39,12 +39,6 @@
// TODO(mbonadei): Remove after the backward compatibility period. // TODO(mbonadei): Remove after the backward compatibility period.
#include "absl/base/internal/thread_annotations.h" // IWYU pragma: export #include "absl/base/internal/thread_annotations.h" // IWYU pragma: export
#if defined(__clang__)
#define ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x))
#else
#define ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) // no-op
#endif
// ABSL_GUARDED_BY() // ABSL_GUARDED_BY()
// //
// Documents if a shared field or global variable needs to be protected by a // Documents if a shared field or global variable needs to be protected by a
...@@ -62,8 +56,11 @@ ...@@ -62,8 +56,11 @@
// int p1_ ABSL_GUARDED_BY(mu_); // int p1_ ABSL_GUARDED_BY(mu_);
// ... // ...
// }; // };
#define ABSL_GUARDED_BY(x) \ #if ABSL_HAVE_ATTRIBUTE(guarded_by)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x)) #define ABSL_GUARDED_BY(x) __attribute__((guarded_by(x)))
#else
#define ABSL_GUARDED_BY(x)
#endif
// ABSL_PT_GUARDED_BY() // ABSL_PT_GUARDED_BY()
// //
...@@ -85,8 +82,11 @@ ...@@ -85,8 +82,11 @@
// // `q_`, guarded by `mu1_`, points to a shared memory location that is // // `q_`, guarded by `mu1_`, points to a shared memory location that is
// // guarded by `mu2_`: // // guarded by `mu2_`:
// int *q_ ABSL_GUARDED_BY(mu1_) ABSL_PT_GUARDED_BY(mu2_); // int *q_ ABSL_GUARDED_BY(mu1_) ABSL_PT_GUARDED_BY(mu2_);
#define ABSL_PT_GUARDED_BY(x) \ #if ABSL_HAVE_ATTRIBUTE(pt_guarded_by)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x)) #define ABSL_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
#else
#define ABSL_PT_GUARDED_BY(x)
#endif
// ABSL_ACQUIRED_AFTER() / ABSL_ACQUIRED_BEFORE() // ABSL_ACQUIRED_AFTER() / ABSL_ACQUIRED_BEFORE()
// //
...@@ -103,11 +103,17 @@ ...@@ -103,11 +103,17 @@
// //
// Mutex m1_; // Mutex m1_;
// Mutex m2_ ABSL_ACQUIRED_AFTER(m1_); // Mutex m2_ ABSL_ACQUIRED_AFTER(m1_);
#define ABSL_ACQUIRED_AFTER(...) \ #if ABSL_HAVE_ATTRIBUTE(acquired_after)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__)) #define ABSL_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
#else
#define ABSL_ACQUIRED_AFTER(...)
#endif
#define ABSL_ACQUIRED_BEFORE(...) \ #if ABSL_HAVE_ATTRIBUTE(acquired_before)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__)) #define ABSL_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
#else
#define ABSL_ACQUIRED_BEFORE(...)
#endif
// ABSL_EXCLUSIVE_LOCKS_REQUIRED() / ABSL_SHARED_LOCKS_REQUIRED() // ABSL_EXCLUSIVE_LOCKS_REQUIRED() / ABSL_SHARED_LOCKS_REQUIRED()
// //
...@@ -132,20 +138,30 @@ ...@@ -132,20 +138,30 @@
// //
// void foo() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } // void foo() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... }
// void bar() const ABSL_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } // void bar() const ABSL_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... }
#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \ #if ABSL_HAVE_ATTRIBUTE(exclusive_locks_required)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ #define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \
exclusive_locks_required(__VA_ARGS__)) __attribute__((exclusive_locks_required(__VA_ARGS__)))
#else
#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...)
#endif
#if ABSL_HAVE_ATTRIBUTE(shared_locks_required)
#define ABSL_SHARED_LOCKS_REQUIRED(...) \ #define ABSL_SHARED_LOCKS_REQUIRED(...) \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_locks_required(__VA_ARGS__)) __attribute__((shared_locks_required(__VA_ARGS__)))
#else
#define ABSL_SHARED_LOCKS_REQUIRED(...)
#endif
// ABSL_LOCKS_EXCLUDED() // ABSL_LOCKS_EXCLUDED()
// //
// Documents the locks acquired in the body of the function. These locks // Documents the locks acquired in the body of the function. These locks
// cannot be held when calling this function (as Abseil's `Mutex` locks are // cannot be held when calling this function (as Abseil's `Mutex` locks are
// non-reentrant). // non-reentrant).
#define ABSL_LOCKS_EXCLUDED(...) \ #if ABSL_HAVE_ATTRIBUTE(locks_excluded)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__)) #define ABSL_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
#else
#define ABSL_LOCKS_EXCLUDED(...)
#endif
// ABSL_LOCK_RETURNED() // ABSL_LOCK_RETURNED()
// //
...@@ -153,8 +169,7 @@ ...@@ -153,8 +169,7 @@
// a public getter method that returns a pointer to a private mutex should // a public getter method that returns a pointer to a private mutex should
// be annotated with ABSL_LOCK_RETURNED. // be annotated with ABSL_LOCK_RETURNED.
#if ABSL_HAVE_ATTRIBUTE(lock_returned) #if ABSL_HAVE_ATTRIBUTE(lock_returned)
#define ABSL_LOCK_RETURNED(x) \ #define ABSL_LOCK_RETURNED(x) __attribute__((lock_returned(x)))
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x))
#else #else
#define ABSL_LOCK_RETURNED(x) #define ABSL_LOCK_RETURNED(x)
#endif #endif
...@@ -162,7 +177,11 @@ ...@@ -162,7 +177,11 @@
// ABSL_LOCKABLE // ABSL_LOCKABLE
// //
// Documents if a class/type is a lockable type (such as the `Mutex` class). // Documents if a class/type is a lockable type (such as the `Mutex` class).
#define ABSL_LOCKABLE ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lockable) #if ABSL_HAVE_ATTRIBUTE(lockable)
#define ABSL_LOCKABLE __attribute__((lockable))
#else
#define ABSL_LOCKABLE
#endif
// ABSL_SCOPED_LOCKABLE // ABSL_SCOPED_LOCKABLE
// //
...@@ -171,30 +190,43 @@ ...@@ -171,30 +190,43 @@
// acquired, and the destructor should use `UNLOCK_FUNCTION()` with no // acquired, and the destructor should use `UNLOCK_FUNCTION()` with no
// arguments; the analysis will assume that the destructor unlocks whatever the // arguments; the analysis will assume that the destructor unlocks whatever the
// constructor locked. // constructor locked.
#define ABSL_SCOPED_LOCKABLE \ #if ABSL_HAVE_ATTRIBUTE(scoped_lockable)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable) #define ABSL_SCOPED_LOCKABLE __attribute__((scoped_lockable))
#else
#define ABSL_SCOPED_LOCKABLE
#endif
// ABSL_EXCLUSIVE_LOCK_FUNCTION() // ABSL_EXCLUSIVE_LOCK_FUNCTION()
// //
// Documents functions that acquire a lock in the body of a function, and do // Documents functions that acquire a lock in the body of a function, and do
// not release it. // not release it.
#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \ #if ABSL_HAVE_ATTRIBUTE(exclusive_lock_function)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ #define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \
exclusive_lock_function(__VA_ARGS__)) __attribute__((exclusive_lock_function(__VA_ARGS__)))
#else
#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...)
#endif
// ABSL_SHARED_LOCK_FUNCTION() // ABSL_SHARED_LOCK_FUNCTION()
// //
// Documents functions that acquire a shared (reader) lock in the body of a // Documents functions that acquire a shared (reader) lock in the body of a
// function, and do not release it. // function, and do not release it.
#if ABSL_HAVE_ATTRIBUTE(shared_lock_function)
#define ABSL_SHARED_LOCK_FUNCTION(...) \ #define ABSL_SHARED_LOCK_FUNCTION(...) \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_lock_function(__VA_ARGS__)) __attribute__((shared_lock_function(__VA_ARGS__)))
#else
#define ABSL_SHARED_LOCK_FUNCTION(...)
#endif
// ABSL_UNLOCK_FUNCTION() // ABSL_UNLOCK_FUNCTION()
// //
// Documents functions that expect a lock to be held on entry to the function, // Documents functions that expect a lock to be held on entry to the function,
// and release it in the body of the function. // and release it in the body of the function.
#define ABSL_UNLOCK_FUNCTION(...) \ #if ABSL_HAVE_ATTRIBUTE(unlock_function)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(unlock_function(__VA_ARGS__)) #define ABSL_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
#else
#define ABSL_UNLOCK_FUNCTION(...)
#endif
// ABSL_EXCLUSIVE_TRYLOCK_FUNCTION() / ABSL_SHARED_TRYLOCK_FUNCTION() // ABSL_EXCLUSIVE_TRYLOCK_FUNCTION() / ABSL_SHARED_TRYLOCK_FUNCTION()
// //
...@@ -204,31 +236,49 @@ ...@@ -204,31 +236,49 @@
// success, or `false` for functions that return `false` on success. The second // success, or `false` for functions that return `false` on success. The second
// argument specifies the mutex that is locked on success. If unspecified, this // argument specifies the mutex that is locked on success. If unspecified, this
// mutex is assumed to be `this`. // mutex is assumed to be `this`.
#if ABSL_HAVE_ATTRIBUTE(exclusive_trylock_function)
#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ #define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ __attribute__((exclusive_trylock_function(__VA_ARGS__)))
exclusive_trylock_function(__VA_ARGS__)) #else
#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...)
#endif
#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \ #if ABSL_HAVE_ATTRIBUTE(shared_trylock_function)
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ #define ABSL_SHARED_TRYLOCK_FUNCTION(...) \
shared_trylock_function(__VA_ARGS__)) __attribute__((shared_trylock_function(__VA_ARGS__)))
#else
#define ABSL_SHARED_TRYLOCK_FUNCTION(...)
#endif
// ABSL_ASSERT_EXCLUSIVE_LOCK() / ABSL_ASSERT_SHARED_LOCK() // ABSL_ASSERT_EXCLUSIVE_LOCK() / ABSL_ASSERT_SHARED_LOCK()
// //
// Documents functions that dynamically check to see if a lock is held, and fail // Documents functions that dynamically check to see if a lock is held, and fail
// if it is not held. // if it is not held.
#if ABSL_HAVE_ATTRIBUTE(assert_exclusive_lock)
#define ABSL_ASSERT_EXCLUSIVE_LOCK(...) \ #define ABSL_ASSERT_EXCLUSIVE_LOCK(...) \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_exclusive_lock(__VA_ARGS__)) __attribute__((assert_exclusive_lock(__VA_ARGS__)))
#else
#define ABSL_ASSERT_EXCLUSIVE_LOCK(...)
#endif
#if ABSL_HAVE_ATTRIBUTE(assert_shared_lock)
#define ABSL_ASSERT_SHARED_LOCK(...) \ #define ABSL_ASSERT_SHARED_LOCK(...) \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_lock(__VA_ARGS__)) __attribute__((assert_shared_lock(__VA_ARGS__)))
#else
#define ABSL_ASSERT_SHARED_LOCK(...)
#endif
// ABSL_NO_THREAD_SAFETY_ANALYSIS // ABSL_NO_THREAD_SAFETY_ANALYSIS
// //
// Turns off thread safety checking within the body of a particular function. // Turns off thread safety checking within the body of a particular function.
// This annotation is used to mark functions that are known to be correct, but // This annotation is used to mark functions that are known to be correct, but
// the locking behavior is more complicated than the analyzer can handle. // the locking behavior is more complicated than the analyzer can handle.
#if ABSL_HAVE_ATTRIBUTE(no_thread_safety_analysis)
#define ABSL_NO_THREAD_SAFETY_ANALYSIS \ #define ABSL_NO_THREAD_SAFETY_ANALYSIS \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis) __attribute__((no_thread_safety_analysis))
#else
#define ABSL_NO_THREAD_SAFETY_ANALYSIS
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Tool-Supplied Annotations // Tool-Supplied Annotations
......
...@@ -150,8 +150,7 @@ TEST(FixedArrayExceptionSafety, InitListConstructorWithAlloc) { ...@@ -150,8 +150,7 @@ TEST(FixedArrayExceptionSafety, InitListConstructorWithAlloc) {
template <typename FixedArrT> template <typename FixedArrT>
testing::AssertionResult ReadMemory(FixedArrT* fixed_arr) { testing::AssertionResult ReadMemory(FixedArrT* fixed_arr) {
// Marked volatile to prevent optimization. Used for running asan tests. int sum = 0;
volatile int sum = 0;
for (const auto& thrower : *fixed_arr) { for (const auto& thrower : *fixed_arr) {
sum += thrower.Get(); sum += thrower.Get();
} }
......
...@@ -1155,7 +1155,8 @@ TEST_F(FormatConvertTest, IntAsDouble) { ...@@ -1155,7 +1155,8 @@ TEST_F(FormatConvertTest, IntAsDouble) {
{__LINE__, StrPrint("%.12a", dx), "%.12a"}, {__LINE__, StrPrint("%.12a", dx), "%.12a"},
}; };
if (native_traits.hex_float_uses_minimal_precision_when_not_specified) { if (native_traits.hex_float_uses_minimal_precision_when_not_specified) {
expect.push_back({__LINE__, StrPrint("%12a", dx), "%12a"}); Expectation ex = {__LINE__, StrPrint("%12a", dx), "%12a"};
expect.push_back(ex);
} }
for (const Expectation &e : expect) { for (const Expectation &e : expect) {
SCOPED_TRACE(e.line); SCOPED_TRACE(e.line);
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
using absl::base_internal::CurrentThreadIdentityIfPresent; using absl::base_internal::CurrentThreadIdentityIfPresent;
using absl::base_internal::PerThreadSynch; using absl::base_internal::PerThreadSynch;
using absl::base_internal::SchedulingGuard;
using absl::base_internal::ThreadIdentity; using absl::base_internal::ThreadIdentity;
using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity; using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity;
using absl::synchronization_internal::GraphCycles; using absl::synchronization_internal::GraphCycles;
...@@ -141,7 +142,9 @@ static const MutexGlobals& GetMutexGlobals() { ...@@ -141,7 +142,9 @@ static const MutexGlobals& GetMutexGlobals() {
namespace { namespace {
enum DelayMode { AGGRESSIVE, GENTLE }; enum DelayMode { AGGRESSIVE, GENTLE };
}; };
static int Delay(int32_t c, DelayMode mode) {
namespace synchronization_internal {
int MutexDelay(int32_t c, int mode) {
// If this a uniprocessor, only yield/sleep. Otherwise, if the mode is // If this a uniprocessor, only yield/sleep. Otherwise, if the mode is
// aggressive then spin many times before yielding. If the mode is // aggressive then spin many times before yielding. If the mode is
// gentle then spin only a few times before yielding. Aggressive spinning is // gentle then spin only a few times before yielding. Aggressive spinning is
...@@ -153,6 +156,7 @@ static int Delay(int32_t c, DelayMode mode) { ...@@ -153,6 +156,7 @@ static int Delay(int32_t c, DelayMode mode) {
// Spin. // Spin.
c++; c++;
} else { } else {
SchedulingGuard::ScopedEnable enable_rescheduling;
ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0); ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0);
if (c == limit) { if (c == limit) {
// Yield once. // Yield once.
...@@ -167,6 +171,7 @@ static int Delay(int32_t c, DelayMode mode) { ...@@ -167,6 +171,7 @@ static int Delay(int32_t c, DelayMode mode) {
} }
return c; return c;
} }
} // namespace synchronization_internal
// --------------------------Generic atomic ops // --------------------------Generic atomic ops
// Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to // Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to
...@@ -1051,6 +1056,7 @@ static PerThreadSynch *DequeueAllWakeable(PerThreadSynch *head, ...@@ -1051,6 +1056,7 @@ static PerThreadSynch *DequeueAllWakeable(PerThreadSynch *head,
// Try to remove thread s from the list of waiters on this mutex. // Try to remove thread s from the list of waiters on this mutex.
// Does nothing if s is not on the waiter list. // Does nothing if s is not on the waiter list.
void Mutex::TryRemove(PerThreadSynch *s) { void Mutex::TryRemove(PerThreadSynch *s) {
SchedulingGuard::ScopedDisable disable_rescheduling;
intptr_t v = mu_.load(std::memory_order_relaxed); intptr_t v = mu_.load(std::memory_order_relaxed);
// acquire spinlock & lock // acquire spinlock & lock
if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait && if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait &&
...@@ -1115,7 +1121,7 @@ ABSL_XRAY_LOG_ARGS(1) void Mutex::Block(PerThreadSynch *s) { ...@@ -1115,7 +1121,7 @@ ABSL_XRAY_LOG_ARGS(1) void Mutex::Block(PerThreadSynch *s) {
this->TryRemove(s); this->TryRemove(s);
int c = 0; int c = 0;
while (s->next != nullptr) { while (s->next != nullptr) {
c = Delay(c, GENTLE); c = synchronization_internal::MutexDelay(c, GENTLE);
this->TryRemove(s); this->TryRemove(s);
} }
if (kDebugMode) { if (kDebugMode) {
...@@ -1894,6 +1900,7 @@ static void CheckForMutexCorruption(intptr_t v, const char* label) { ...@@ -1894,6 +1900,7 @@ static void CheckForMutexCorruption(intptr_t v, const char* label) {
} }
void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
SchedulingGuard::ScopedDisable disable_rescheduling;
int c = 0; int c = 0;
intptr_t v = mu_.load(std::memory_order_relaxed); intptr_t v = mu_.load(std::memory_order_relaxed);
if ((v & kMuEvent) != 0) { if ((v & kMuEvent) != 0) {
...@@ -1995,7 +2002,8 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { ...@@ -1995,7 +2002,8 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
ABSL_RAW_CHECK( ABSL_RAW_CHECK(
waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
"detected illegal recursion into Mutex code"); "detected illegal recursion into Mutex code");
c = Delay(c, GENTLE); // delay, then try again // delay, then try again
c = synchronization_internal::MutexDelay(c, GENTLE);
} }
ABSL_RAW_CHECK( ABSL_RAW_CHECK(
waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
...@@ -2013,6 +2021,7 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { ...@@ -2013,6 +2021,7 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
// or it is in the process of blocking on a condition variable; it must requeue // or it is in the process of blocking on a condition variable; it must requeue
// itself on the mutex/condvar to wait for its condition to become true. // itself on the mutex/condvar to wait for its condition to become true.
ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) {
SchedulingGuard::ScopedDisable disable_rescheduling;
intptr_t v = mu_.load(std::memory_order_relaxed); intptr_t v = mu_.load(std::memory_order_relaxed);
this->AssertReaderHeld(); this->AssertReaderHeld();
CheckForMutexCorruption(v, "Unlock"); CheckForMutexCorruption(v, "Unlock");
...@@ -2289,7 +2298,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { ...@@ -2289,7 +2298,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) {
mu_.store(nv, std::memory_order_release); mu_.store(nv, std::memory_order_release);
break; // out of for(;;)-loop break; // out of for(;;)-loop
} }
c = Delay(c, AGGRESSIVE); // aggressive here; no one can proceed till we do // aggressive here; no one can proceed till we do
c = synchronization_internal::MutexDelay(c, AGGRESSIVE);
} // end of for(;;)-loop } // end of for(;;)-loop
if (wake_list != kPerThreadSynchNull) { if (wake_list != kPerThreadSynchNull) {
...@@ -2328,6 +2338,7 @@ void Mutex::Trans(MuHow how) { ...@@ -2328,6 +2338,7 @@ void Mutex::Trans(MuHow how) {
// It will later acquire the mutex with high probability. Otherwise, we // It will later acquire the mutex with high probability. Otherwise, we
// enqueue thread w on this mutex. // enqueue thread w on this mutex.
void Mutex::Fer(PerThreadSynch *w) { void Mutex::Fer(PerThreadSynch *w) {
SchedulingGuard::ScopedDisable disable_rescheduling;
int c = 0; int c = 0;
ABSL_RAW_CHECK(w->waitp->cond == nullptr, ABSL_RAW_CHECK(w->waitp->cond == nullptr,
"Mutex::Fer while waiting on Condition"); "Mutex::Fer while waiting on Condition");
...@@ -2377,7 +2388,7 @@ void Mutex::Fer(PerThreadSynch *w) { ...@@ -2377,7 +2388,7 @@ void Mutex::Fer(PerThreadSynch *w) {
return; return;
} }
} }
c = Delay(c, GENTLE); c = synchronization_internal::MutexDelay(c, GENTLE);
} }
} }
...@@ -2426,6 +2437,7 @@ CondVar::~CondVar() { ...@@ -2426,6 +2437,7 @@ CondVar::~CondVar() {
// Remove thread s from the list of waiters on this condition variable. // Remove thread s from the list of waiters on this condition variable.
void CondVar::Remove(PerThreadSynch *s) { void CondVar::Remove(PerThreadSynch *s) {
SchedulingGuard::ScopedDisable disable_rescheduling;
intptr_t v; intptr_t v;
int c = 0; int c = 0;
for (v = cv_.load(std::memory_order_relaxed);; for (v = cv_.load(std::memory_order_relaxed);;
...@@ -2454,7 +2466,8 @@ void CondVar::Remove(PerThreadSynch *s) { ...@@ -2454,7 +2466,8 @@ void CondVar::Remove(PerThreadSynch *s) {
std::memory_order_release); std::memory_order_release);
return; return;
} else { } else {
c = Delay(c, GENTLE); // try again after a delay // try again after a delay
c = synchronization_internal::MutexDelay(c, GENTLE);
} }
} }
} }
...@@ -2487,7 +2500,7 @@ static void CondVarEnqueue(SynchWaitParams *waitp) { ...@@ -2487,7 +2500,7 @@ static void CondVarEnqueue(SynchWaitParams *waitp) {
!cv_word->compare_exchange_weak(v, v | kCvSpin, !cv_word->compare_exchange_weak(v, v | kCvSpin,
std::memory_order_acquire, std::memory_order_acquire,
std::memory_order_relaxed)) { std::memory_order_relaxed)) {
c = Delay(c, GENTLE); c = synchronization_internal::MutexDelay(c, GENTLE);
v = cv_word->load(std::memory_order_relaxed); v = cv_word->load(std::memory_order_relaxed);
} }
ABSL_RAW_CHECK(waitp->thread->waitp == nullptr, "waiting when shouldn't be"); ABSL_RAW_CHECK(waitp->thread->waitp == nullptr, "waiting when shouldn't be");
...@@ -2586,6 +2599,7 @@ void CondVar::Wakeup(PerThreadSynch *w) { ...@@ -2586,6 +2599,7 @@ void CondVar::Wakeup(PerThreadSynch *w) {
} }
void CondVar::Signal() { void CondVar::Signal() {
SchedulingGuard::ScopedDisable disable_rescheduling;
ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0); ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0);
intptr_t v; intptr_t v;
int c = 0; int c = 0;
...@@ -2618,7 +2632,7 @@ void CondVar::Signal() { ...@@ -2618,7 +2632,7 @@ void CondVar::Signal() {
ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
return; return;
} else { } else {
c = Delay(c, GENTLE); c = synchronization_internal::MutexDelay(c, GENTLE);
} }
} }
ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
...@@ -2655,7 +2669,8 @@ void CondVar::SignalAll () { ...@@ -2655,7 +2669,8 @@ void CondVar::SignalAll () {
ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
return; return;
} else { } else {
c = Delay(c, GENTLE); // try again after a delay // try again after a delay
c = synchronization_internal::MutexDelay(c, GENTLE);
} }
} }
ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
......
...@@ -95,15 +95,14 @@ class TimeZoneInfo : public TimeZoneIf { ...@@ -95,15 +95,14 @@ class TimeZoneInfo : public TimeZoneIf {
std::size_t DataLength(std::size_t time_len) const; std::size_t DataLength(std::size_t time_len) const;
}; };
void CheckTransition(const std::string& name, const TransitionType& tt, bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
std::int_fast32_t offset, bool is_dst, const std::string& abbr, std::uint_fast8_t* index);
const std::string& abbr) const;
bool EquivTransitions(std::uint_fast8_t tt1_index, bool EquivTransitions(std::uint_fast8_t tt1_index,
std::uint_fast8_t tt2_index) const; std::uint_fast8_t tt2_index) const;
void ExtendTransitions(const std::string& name, const Header& hdr); bool ExtendTransitions();
bool ResetToBuiltinUTC(const seconds& offset); bool ResetToBuiltinUTC(const seconds& offset);
bool Load(const std::string& name, ZoneInfoSource* zip); bool Load(ZoneInfoSource* zip);
// Helpers for BreakTime() and MakeTime(). // Helpers for BreakTime() and MakeTime().
time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
......
...@@ -71,15 +71,16 @@ for std in ${STD}; do ...@@ -71,15 +71,16 @@ for std in ${STD}; do
-e CC="/opt/llvm/clang/bin/clang" \ -e CC="/opt/llvm/clang/bin/clang" \
-e BAZEL_COMPILER="llvm" \ -e BAZEL_COMPILER="llvm" \
-e BAZEL_CXXOPTS="-std=${std}" \ -e BAZEL_CXXOPTS="-std=${std}" \
-e CPLUS_INCLUDE_PATH="/usr/include/c++/8" \
${DOCKER_EXTRA_ARGS:-} \ ${DOCKER_EXTRA_ARGS:-} \
${DOCKER_CONTAINER} \ ${DOCKER_CONTAINER} \
/usr/local/bin/bazel test ... \ /usr/local/bin/bazel test ... \
--compilation_mode="${compilation_mode}" \ --compilation_mode="${compilation_mode}" \
--copt="--gcc-toolchain=/usr/local" \
--copt="${exceptions_mode}" \ --copt="${exceptions_mode}" \
--copt=-Werror \ --copt=-Werror \
--define="absl=1" \ --define="absl=1" \
--keep_going \ --keep_going \
--linkopt="--gcc-toolchain=/usr/local" \
--show_timestamps \ --show_timestamps \
--test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \ --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
--test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \ --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
......
...@@ -16,6 +16,6 @@ ...@@ -16,6 +16,6 @@
# Test scripts should source this file to get the identifiers. # Test scripts should source this file to get the identifiers.
readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20191016" readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20191016"
readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20200706" readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200710"
readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20200319" readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200710"
readonly LINUX_GCC_49_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-4.9:20191018" readonly LINUX_GCC_49_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-4.9:20191018"
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