1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++98, c++03
11 #define TESTING_CXA_GUARD
12 #include "../src/cxa_guard_impl.h"
15 using namespace __cxxabiv1
;
17 template <class GuardType
, class Impl
>
20 Tests() : g
{}, impl(&g
) {}
24 uint8_t first_byte() {
26 std::memcpy(&first
, &g
, 1);
30 void reset() { g
= {}; }
33 // Test the post conditions on cxa_guard_acquire, cxa_guard_abort, and
34 // cxa_guard_release. Specifically, that they leave the first byte with
35 // the value 0 or 1 as specified by the ARM or Itanium specification.
46 assert(first_byte() == 0);
47 assert(impl
.cxa_guard_acquire() == INIT_IS_PENDING
);
48 assert(first_byte() == 0);
52 assert(first_byte() == 0);
53 assert(impl
.cxa_guard_acquire() == INIT_IS_PENDING
);
54 impl
.cxa_guard_release();
55 assert(first_byte() == 1);
56 assert(impl
.cxa_guard_acquire() == INIT_IS_DONE
);
63 assert(first_byte() == 0);
64 assert(impl
.cxa_guard_acquire() == INIT_IS_PENDING
);
65 assert(first_byte() == 0);
66 impl
.cxa_guard_release();
67 assert(first_byte() == 1);
74 assert(first_byte() == 0);
75 assert(impl
.cxa_guard_acquire() == INIT_IS_PENDING
);
76 assert(first_byte() == 0);
77 impl
.cxa_guard_abort();
78 assert(first_byte() == 0);
79 assert(impl
.cxa_guard_acquire() == INIT_IS_PENDING
);
80 assert(first_byte() == 0);
98 bool is_locked
= false;
100 NopMutex global_nop_mutex
= {};
103 bool broadcast() { return false; }
104 bool wait(NopMutex
&) { return false; }
106 NopCondVar global_nop_cond
= {};
108 void NopFutexWait(int*, int) { assert(false); }
109 void NopFutexWake(int*) { assert(false); }
110 uint32_t MockGetThreadID() { return 0; }
114 #if defined(_LIBCXXABI_HAS_NO_THREADS)
115 static_assert(CurrentImplementation
== Implementation::NoThreads
, "");
117 std::is_same
<SelectedImplementation
, InitByteNoThreads
>::value
, "");
119 static_assert(CurrentImplementation
== Implementation::GlobalLock
, "");
122 SelectedImplementation
,
123 InitByteGlobalMutex
<LibcppMutex
, LibcppCondVar
,
124 GlobalStatic
<LibcppMutex
>::instance
,
125 GlobalStatic
<LibcppCondVar
>::instance
>>::value
,
130 #if (defined(__APPLE__) || defined(__linux__)) && !defined(_LIBCXXABI_HAS_NO_THREADS)
131 assert(PlatformThreadID
);
133 if (PlatformSupportsThreadID()) {
134 assert(PlatformThreadID() != 0);
135 assert(PlatformThreadID() == PlatformThreadID());
139 Tests
<uint32_t, InitByteNoThreads
>::test();
140 Tests
<uint64_t, InitByteNoThreads
>::test();
144 InitByteGlobalMutex
<NopMutex
, NopCondVar
, global_nop_mutex
,
145 global_nop_cond
, MockGetThreadID
>;
146 Tests
<uint32_t, MutexImpl
>::test();
147 Tests
<uint64_t, MutexImpl
>::test();
151 InitByteFutex
<&NopFutexWait
, &NopFutexWake
, &MockGetThreadID
>;
152 Tests
<uint32_t, FutexImpl
>::test();
153 Tests
<uint64_t, FutexImpl
>::test();