Export of internal Abseil changes

--
517dc7eba9878290fc93c6523dc6d6e2c49b8c1e by Abseil Team <absl-team@google.com>:

Handle 'nan' in HumanReadableInt::ToInt64.

PiperOrigin-RevId: 318121226

--
4fa6103b46dbc1375d416810dba591ab4f4898d1 by Abseil Team <absl-team@google.com>:

Promote `float`s to `double`s before formatting.

This will bring StrFormat behavior more in line with that of sprintf.

PiperOrigin-RevId: 318091841

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

Google-internal changes only.

PiperOrigin-RevId: 318069900

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

Inclusive language fix: Stop using blacklist/whitelist terminology in Abseil.

PiperOrigin-RevId: 317925379

--
52b56a27a773ea7c10ea8fd456ed606b9d778947 by Abseil Team <absl-team@google.com>:

Add test for floats and label tests for double properly.

PiperOrigin-RevId: 317916380

--
0f405960ab5b34d673244fda8bb9141c8f5c1a4f by Abseil Team <absl-team@google.com>:

Remove the static initialization of global variables used by absl::Mutex
as requested by Chromium

PiperOrigin-RevId: 317911430

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

Internal Change

PiperOrigin-RevId: 317864956

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

Swap ABSL_DLL / ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES order to fix clang-cl builds.

PiperOrigin-RevId: 317858053

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

Migrate use of annotation macros to ABSL namespaced names

PiperOrigin-RevId: 317792057
GitOrigin-RevId: 517dc7eba9878290fc93c6523dc6d6e2c49b8c1e
Change-Id: I1a0c04d01adbdc5106b68fd69c97c31f822e11dc
pull/724/head
Abseil Team 5 years ago committed by Mark Barolak
parent 10cb35e459
commit b86fff162e
  1. 2
      absl/base/internal/low_level_alloc.cc
  2. 7
      absl/base/internal/low_level_scheduling.h
  3. 4
      absl/base/internal/raw_logging.cc
  4. 2
      absl/base/internal/raw_logging.h
  5. 6
      absl/base/internal/unscaledcycleclock.h
  6. 16
      absl/container/fixed_array.h
  7. 4
      absl/debugging/symbolize_elf.inc
  8. 158
      absl/strings/internal/str_format/convert_test.cc
  9. 2
      absl/strings/internal/str_format/float_conversion.cc
  10. 6
      absl/strings/numbers_test.cc
  11. 2
      absl/synchronization/internal/per_thread_sem.h
  12. 68
      absl/synchronization/mutex.cc
  13. 1
      absl/types/BUILD.bazel

@ -598,7 +598,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
section.Leave();
result = &s->levels;
}
ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request);
ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request);
return result;
}

@ -29,6 +29,9 @@ extern "C" void __google_enable_rescheduling(bool disable_result);
namespace absl {
ABSL_NAMESPACE_BEGIN
class CondVar;
class Mutex;
namespace base_internal {
class SchedulingHelper; // To allow use of SchedulingGuard.
@ -76,7 +79,9 @@ class SchedulingGuard {
bool disabled;
};
// Access to SchedulingGuard is explicitly white-listed.
// Access to SchedulingGuard is explicitly permitted.
friend class absl::CondVar;
friend class absl::Mutex;
friend class SchedulingHelper;
friend class SpinLock;

@ -69,7 +69,7 @@
// TODO(gfalcon): We want raw-logging to work on as many platforms as possible.
// Explicitly #error out when not ABSL_LOW_LEVEL_WRITE_SUPPORTED, except for a
// whitelisted set of platforms for which we expect not to be able to raw log.
// selected set of platforms for which we expect not to be able to raw log.
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static absl::base_internal::AtomicHook<
absl::raw_logging_internal::LogPrefixHook>
@ -227,7 +227,7 @@ bool RawLoggingFullySupported() {
#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
}
ABSL_DLL ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL
absl::base_internal::AtomicHook<InternalLogFunction>
internal_log_function(DefaultInternalLog);

@ -170,7 +170,7 @@ using InternalLogFunction = void (*)(absl::LogSeverity severity,
const char* file, int line,
const std::string& message);
ABSL_DLL ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES extern base_internal::AtomicHook<
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL extern base_internal::AtomicHook<
InternalLogFunction>
internal_log_function;

@ -15,8 +15,8 @@
// UnscaledCycleClock
// An UnscaledCycleClock yields the value and frequency of a cycle counter
// that increments at a rate that is approximately constant.
// This class is for internal / whitelisted use only, you should consider
// using CycleClock instead.
// This class is for internal use only, you should consider using CycleClock
// instead.
//
// Notes:
// The cycle counter frequency is not necessarily the core clock frequency.
@ -109,7 +109,7 @@ class UnscaledCycleClock {
// value.
static double Frequency();
// Whitelisted friends.
// Allowed users
friend class base_internal::CycleClock;
friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime;
friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency;

@ -428,9 +428,9 @@ class FixedArray {
#endif // ADDRESS_SANITIZER
private:
ADDRESS_SANITIZER_REDZONE(redzone_begin_);
ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_);
alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])];
ADDRESS_SANITIZER_REDZONE(redzone_end_);
ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_);
};
class EmptyInlinedStorage {
@ -505,8 +505,10 @@ void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct(
typename FixedArray<T, N, A>::size_type n) {
#ifdef ADDRESS_SANITIZER
if (!n) return;
ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), data() + n);
ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(), RedzoneBegin());
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(),
data() + n);
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(),
RedzoneBegin());
#endif // ADDRESS_SANITIZER
static_cast<void>(n); // Mark used when not in asan mode
}
@ -516,8 +518,10 @@ void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateDestruct(
typename FixedArray<T, N, A>::size_type n) {
#ifdef ADDRESS_SANITIZER
if (!n) return;
ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, RedzoneEnd());
ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(), data());
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n,
RedzoneEnd());
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(),
data());
#endif // ADDRESS_SANITIZER
static_cast<void>(n); // Mark used when not in asan mode
}

@ -1455,7 +1455,7 @@ bool GetFileMappingHint(const void **start, const void **end, uint64_t *offset,
bool Symbolize(const void *pc, char *out, int out_size) {
// Symbolization is very slow under tsan.
ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
SAFE_ASSERT(out_size >= 0);
debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer();
const char *name = s->GetSymbol(pc);
@ -1474,7 +1474,7 @@ bool Symbolize(const void *pc, char *out, int out_size) {
}
}
debugging_internal::FreeSymbolizer(s);
ANNOTATE_IGNORE_READS_AND_WRITES_END();
ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
return ok;
}

@ -474,6 +474,57 @@ TEST_F(FormatConvertTest, Uint128) {
}
}
template <typename Floating>
void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
// Reserve the space to ensure we don't allocate memory in the output itself.
std::string str_format_result;
str_format_result.reserve(1 << 20);
std::string string_printf_result;
string_printf_result.reserve(1 << 20);
const char *const kFormats[] = {
"%", "%.3", "%8.5", "%500", "%.5000", "%.60", "%.30", "%03",
"%+", "% ", "%-10", "%#15.3", "%#.0", "%.0", "%1$*2$", "%1$.*2$"};
for (const char *fmt : kFormats) {
for (char f : {'f', 'F', //
'g', 'G', //
'a', 'A', //
'e', 'E'}) {
std::string fmt_str = std::string(fmt) + f;
if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F') {
// This particular test takes way too long with snprintf.
// Disable for the case we are not implementing natively.
continue;
}
for (Floating d : floats) {
int i = -10;
FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
UntypedFormatSpecImpl format(fmt_str);
string_printf_result.clear();
StrAppend(&string_printf_result, fmt_str.c_str(), d, i);
str_format_result.clear();
{
AppendPack(&str_format_result, format, absl::MakeSpan(args));
}
if (string_printf_result != str_format_result) {
// We use ASSERT_EQ here because failures are usually correlated and a
// bug would print way too many failed expectations causing the test
// to time out.
ASSERT_EQ(string_printf_result, str_format_result)
<< fmt_str << " " << StrPrint("%.18g", d) << " "
<< StrPrint("%a", d) << " " << StrPrint("%.50f", d);
}
}
}
}
}
TEST_F(FormatConvertTest, Float) {
#ifdef _MSC_VER
// MSVC has a different rounding policy than us so we can't test our
@ -481,9 +532,62 @@ TEST_F(FormatConvertTest, Float) {
return;
#endif // _MSC_VER
const char *const kFormats[] = {
"%", "%.3", "%8.5", "%500", "%.5000", "%.60", "%.30", "%03",
"%+", "% ", "%-10", "%#15.3", "%#.0", "%.0", "%1$*2$", "%1$.*2$"};
std::vector<float> floats = {0.0f,
-0.0f,
.9999999f,
9999999.f,
std::numeric_limits<float>::max(),
-std::numeric_limits<float>::max(),
std::numeric_limits<float>::min(),
-std::numeric_limits<float>::min(),
std::numeric_limits<float>::lowest(),
-std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::epsilon(),
std::numeric_limits<float>::epsilon() + 1.0f,
std::numeric_limits<float>::infinity(),
-std::numeric_limits<float>::infinity()};
// Some regression tests.
floats.push_back(0.999999989f);
if (std::numeric_limits<float>::has_denorm != std::denorm_absent) {
floats.push_back(std::numeric_limits<float>::denorm_min());
floats.push_back(-std::numeric_limits<float>::denorm_min());
}
for (float base :
{1.f, 12.f, 123.f, 1234.f, 12345.f, 123456.f, 1234567.f, 12345678.f,
123456789.f, 1234567890.f, 12345678901.f, 12345678.f, 12345678.f}) {
for (int exp = -123; exp <= 123; ++exp) {
for (int sign : {1, -1}) {
floats.push_back(sign * std::ldexp(base, exp));
}
}
}
for (int exp = -300; exp <= 300; ++exp) {
const float all_ones_mantissa = 0xffffff;
floats.push_back(std::ldexp(all_ones_mantissa, exp));
}
// Remove duplicates to speed up the logic below.
std::sort(floats.begin(), floats.end());
floats.erase(std::unique(floats.begin(), floats.end()), floats.end());
#ifndef __APPLE__
// Apple formats NaN differently (+nan) vs. (nan)
floats.push_back(std::nan(""));
#endif
TestWithMultipleFormatsHelper(floats);
}
TEST_F(FormatConvertTest, Double) {
#ifdef _MSC_VER
// MSVC has a different rounding policy than us so we can't test our
// implementation against the native one there.
return;
#endif // _MSC_VER
std::vector<double> doubles = {0.0,
-0.0,
@ -554,52 +658,10 @@ TEST_F(FormatConvertTest, Float) {
doubles.push_back(std::nan(""));
#endif
// Reserve the space to ensure we don't allocate memory in the output itself.
std::string str_format_result;
str_format_result.reserve(1 << 20);
std::string string_printf_result;
string_printf_result.reserve(1 << 20);
for (const char *fmt : kFormats) {
for (char f : {'f', 'F', //
'g', 'G', //
'a', 'A', //
'e', 'E'}) {
std::string fmt_str = std::string(fmt) + f;
if (fmt == absl::string_view("%.5000") && f != 'f' && f != 'F') {
// This particular test takes way too long with snprintf.
// Disable for the case we are not implementing natively.
continue;
}
for (double d : doubles) {
int i = -10;
FormatArgImpl args[2] = {FormatArgImpl(d), FormatArgImpl(i)};
UntypedFormatSpecImpl format(fmt_str);
string_printf_result.clear();
StrAppend(&string_printf_result, fmt_str.c_str(), d, i);
str_format_result.clear();
{
AppendPack(&str_format_result, format, absl::MakeSpan(args));
}
if (string_printf_result != str_format_result) {
// We use ASSERT_EQ here because failures are usually correlated and a
// bug would print way too many failed expectations causing the test
// to time out.
ASSERT_EQ(string_printf_result, str_format_result)
<< fmt_str << " " << StrPrint("%.18g", d) << " "
<< StrPrint("%a", d) << " " << StrPrint("%.1080f", d);
}
}
}
}
TestWithMultipleFormatsHelper(doubles);
}
TEST_F(FormatConvertTest, FloatRound) {
TEST_F(FormatConvertTest, DoubleRound) {
std::string s;
const auto format = [&](const char *fmt, double d) -> std::string & {
s.clear();
@ -797,7 +859,7 @@ TEST_F(FormatConvertTest, LongDouble) {
}
}
TEST_F(FormatConvertTest, IntAsFloat) {
TEST_F(FormatConvertTest, IntAsDouble) {
const int kMin = std::numeric_limits<int>::min();
const int kMax = std::numeric_limits<int>::max();
const int ia[] = {

@ -1131,7 +1131,7 @@ bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv,
bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv,
FormatSinkImpl *sink) {
return FloatToSink(v, conv, sink);
return FloatToSink(static_cast<double>(v), conv, sink);
}
bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv,

@ -359,6 +359,12 @@ TEST(NumbersTest, Atoi) {
VerifySimpleAtoiGood<std::string::size_type>(42, 42);
}
TEST(NumbersTest, Atod) {
double d;
EXPECT_TRUE(absl::SimpleAtod("nan", &d));
EXPECT_TRUE(std::isnan(d));
}
TEST(NumbersTest, Atoenum) {
enum E01 {
E01_zero = 0,

@ -78,7 +78,7 @@ class PerThreadSem {
// !t.has_timeout() => Wait(t) will return true.
static inline bool Wait(KernelTimeout t);
// White-listed callers.
// Permitted callers.
friend class PerThreadSemTest;
friend class absl::Mutex;
friend absl::base_internal::ThreadIdentity* CreateThreadIdentity();

@ -39,7 +39,6 @@
#include <thread> // NOLINT(build/c++11)
#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/atomic_hook.h"
@ -59,6 +58,7 @@
using absl::base_internal::CurrentThreadIdentityIfPresent;
using absl::base_internal::PerThreadSynch;
using absl::base_internal::SchedulingGuard;
using absl::base_internal::ThreadIdentity;
using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity;
using absl::synchronization_internal::GraphCycles;
@ -86,6 +86,28 @@ ABSL_CONST_INIT std::atomic<OnDeadlockCycle> synch_deadlock_detection(
kDeadlockDetectionDefault);
ABSL_CONST_INIT std::atomic<bool> synch_check_invariants(false);
// ------------------------------------------ spinlock support
// Make sure read-only globals used in the Mutex code are contained on the
// same cacheline and cacheline aligned to eliminate any false sharing with
// other globals from this and other modules.
static struct MutexGlobals {
MutexGlobals() {
// Find machine-specific data needed for Delay() and
// TryAcquireWithSpinning(). This runs in the global constructor
// sequence, and before that zeros are safe values.
num_cpus = absl::base_internal::NumCPUs();
spinloop_iterations = num_cpus > 1 ? 1500 : 0;
}
int num_cpus;
int spinloop_iterations;
// Pad this struct to a full cacheline to prevent false sharing.
char padding[ABSL_CACHELINE_SIZE - 2 * sizeof(int)];
} ABSL_CACHELINE_ALIGNED mutex_globals;
static_assert(
sizeof(MutexGlobals) == ABSL_CACHELINE_SIZE,
"MutexGlobals must occupy an entire cacheline to prevent false sharing");
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)>
submit_profile_data;
@ -122,22 +144,7 @@ void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size)) {
symbolizer.Store(fn);
}
struct ABSL_CACHELINE_ALIGNED MutexGlobals {
absl::once_flag once;
int num_cpus = 0;
int spinloop_iterations = 0;
};
static const MutexGlobals& GetMutexGlobals() {
ABSL_CONST_INIT static MutexGlobals data;
absl::base_internal::LowLevelCallOnce(&data.once, [&]() {
data.num_cpus = absl::base_internal::NumCPUs();
data.spinloop_iterations = data.num_cpus > 1 ? 1500 : 0;
});
return data;
}
// Spinlock delay on iteration c. Returns new c.
// spinlock delay on iteration c. Returns new c.
namespace {
enum DelayMode { AGGRESSIVE, GENTLE };
};
@ -147,25 +154,22 @@ static int Delay(int32_t c, DelayMode mode) {
// gentle then spin only a few times before yielding. Aggressive spinning is
// used to ensure that an Unlock() call, which must get the spin lock for
// any thread to make progress gets it without undue delay.
const int32_t limit =
GetMutexGlobals().num_cpus > 1 ? (mode == AGGRESSIVE ? 5000 : 250) : 0;
int32_t limit = (mutex_globals.num_cpus > 1) ?
((mode == AGGRESSIVE) ? 5000 : 250) : 0;
if (c < limit) {
// Spin.
c++;
c++; // spin
} else {
ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0);
if (c == limit) {
// Yield once.
if (c == limit) { // yield once
AbslInternalMutexYield();
c++;
} else {
// Then wait.
} else { // then wait
absl::SleepFor(absl::Microseconds(10));
c = 0;
}
ABSL_TSAN_MUTEX_POST_DIVERT(nullptr, 0);
}
return c;
return (c);
}
// --------------------------Generic atomic ops
@ -1051,6 +1055,7 @@ static PerThreadSynch *DequeueAllWakeable(PerThreadSynch *head,
// Try to remove thread s from the list of waiters on this mutex.
// Does nothing if s is not on the waiter list.
void Mutex::TryRemove(PerThreadSynch *s) {
SchedulingGuard::ScopedDisable disable_rescheduling;
intptr_t v = mu_.load(std::memory_order_relaxed);
// acquire spinlock & lock
if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait &&
@ -1434,7 +1439,7 @@ void Mutex::AssertNotHeld() const {
// Attempt to acquire *mu, and return whether successful. The implementation
// may spin for a short while if the lock cannot be acquired immediately.
static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) {
int c = GetMutexGlobals().spinloop_iterations;
int c = mutex_globals.spinloop_iterations;
do { // do/while somewhat faster on AMD
intptr_t v = mu->load(std::memory_order_relaxed);
if ((v & (kMuReader|kMuEvent)) != 0) {
@ -1811,9 +1816,9 @@ static inline bool EvalConditionIgnored(Mutex *mu, const Condition *cond) {
// So we "divert" (which un-ignores both memory accesses and synchronization)
// and then separately turn on ignores of memory accesses.
ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
bool res = cond->Eval();
ANNOTATE_IGNORE_READS_AND_WRITES_END();
ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
static_cast<void>(mu); // Prevent unused param warning in non-TSAN builds.
return res;
@ -1894,6 +1899,7 @@ static void CheckForMutexCorruption(intptr_t v, const char* label) {
}
void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
SchedulingGuard::ScopedDisable disable_rescheduling;
int c = 0;
intptr_t v = mu_.load(std::memory_order_relaxed);
if ((v & kMuEvent) != 0) {
@ -2013,6 +2019,7 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
// 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.
ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) {
SchedulingGuard::ScopedDisable disable_rescheduling;
intptr_t v = mu_.load(std::memory_order_relaxed);
this->AssertReaderHeld();
CheckForMutexCorruption(v, "Unlock");
@ -2328,6 +2335,7 @@ void Mutex::Trans(MuHow how) {
// It will later acquire the mutex with high probability. Otherwise, we
// enqueue thread w on this mutex.
void Mutex::Fer(PerThreadSynch *w) {
SchedulingGuard::ScopedDisable disable_rescheduling;
int c = 0;
ABSL_RAW_CHECK(w->waitp->cond == nullptr,
"Mutex::Fer while waiting on Condition");
@ -2426,6 +2434,7 @@ CondVar::~CondVar() {
// Remove thread s from the list of waiters on this condition variable.
void CondVar::Remove(PerThreadSynch *s) {
SchedulingGuard::ScopedDisable disable_rescheduling;
intptr_t v;
int c = 0;
for (v = cv_.load(std::memory_order_relaxed);;
@ -2586,6 +2595,7 @@ void CondVar::Wakeup(PerThreadSynch *w) {
}
void CondVar::Signal() {
SchedulingGuard::ScopedDisable disable_rescheduling;
ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0);
intptr_t v;
int c = 0;

@ -12,7 +12,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load(

Loading…
Cancel
Save