Bug 1889091 - Part 3: Specialize calls to native functions with variadic parameters...
[gecko.git] / mfbt / tests / TestAtomicBitfields.cpp
blob237dbde538a50283177edfb2f6d2dee2e94ca902
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Assertions.h"
8 #include "mozilla/AtomicBitfields.h"
10 // This is a big macro mess, so let's summarize what's in here right up front:
12 // |TestDocumentationExample| is intended to be a copy-paste of the example
13 // in the macro's documentation, to make sure it's correct.
16 // |TestJammedWithFlags| tests using every bit of the type for bool flags.
17 // 64-bit isn't tested due to macro limitations.
20 // |TestLopsided| tests an instance with the following configuration:
22 // * a 1-bit boolean
23 // * an (N-1)-bit uintN_t
25 // It tests both orderings of these fields.
27 // Hopefully these are enough to cover all the nasty boundary conditions
28 // (that still compile).
30 // ==================== TestDocumentationExample ========================
32 struct MyType {
33 MOZ_ATOMIC_BITFIELDS(mAtomicFields, 8,
34 ((bool, IsDownloaded, 1), (uint32_t, SomeData, 2),
35 (uint8_t, OtherData, 5)))
37 int32_t aNormalInteger;
39 explicit MyType(uint32_t aSomeData) : aNormalInteger(7) {
40 StoreSomeData(aSomeData);
41 // Other bitfields were already default initialized to 0/false
45 void TestDocumentationExample() {
46 MyType val(3);
48 if (!val.LoadIsDownloaded()) {
49 val.StoreOtherData(2);
50 val.StoreIsDownloaded(true);
54 // ====================== TestJammedWithFlags =========================
56 #define TIMES_8(aFunc, aSeparator, aArgs) \
57 MOZ_FOR_EACH_SEPARATED(aFunc, aSeparator, aArgs, (1, 2, 3, 4, 5, 6, 7, 8))
58 #define TIMES_16(aFunc, aSeparator, aArgs) \
59 MOZ_FOR_EACH_SEPARATED( \
60 aFunc, aSeparator, aArgs, \
61 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))
62 #define TIMES_32(aFunc, aSeparator, aArgs) \
63 MOZ_FOR_EACH_SEPARATED( \
64 aFunc, aSeparator, aArgs, \
65 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, \
66 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32))
68 #define CHECK_BOOL(aIndex) \
69 MOZ_ASSERT(val.LoadFlag##aIndex() == false); \
70 val.StoreFlag##aIndex(true); \
71 MOZ_ASSERT(val.LoadFlag##aIndex() == true); \
72 val.StoreFlag##aIndex(false); \
73 MOZ_ASSERT(val.LoadFlag##aIndex() == false);
75 #define GENERATE_TEST_JAMMED_WITH_FLAGS(aSize) \
76 void TestJammedWithFlags##aSize() { \
77 JammedWithFlags##aSize val; \
78 TIMES_##aSize(CHECK_BOOL, (;), ()); \
81 #define TEST_JAMMED_WITH_FLAGS(aSize) TestJammedWithFlags##aSize();
83 // ========================= TestLopsided ===========================
85 #define GENERATE_TEST_LOPSIDED_FUNC(aSide, aSize) \
86 void TestLopsided##aSide##aSize() { \
87 Lopsided##aSide##aSize val; \
88 MOZ_ASSERT(val.LoadHappyLittleBit() == false); \
89 MOZ_ASSERT(val.LoadLargeAndInCharge() == 0); \
90 val.StoreHappyLittleBit(true); \
91 MOZ_ASSERT(val.LoadHappyLittleBit() == true); \
92 MOZ_ASSERT(val.LoadLargeAndInCharge() == 0); \
93 val.StoreLargeAndInCharge(1); \
94 MOZ_ASSERT(val.LoadHappyLittleBit() == true); \
95 MOZ_ASSERT(val.LoadLargeAndInCharge() == 1); \
96 val.StoreLargeAndInCharge(0); \
97 MOZ_ASSERT(val.LoadHappyLittleBit() == true); \
98 MOZ_ASSERT(val.LoadLargeAndInCharge() == 0); \
99 uint##aSize##_t size = aSize; \
100 uint##aSize##_t int_max = (~(1ull << (size - 1))) - 1; \
101 val.StoreLargeAndInCharge(int_max); \
102 MOZ_ASSERT(val.LoadHappyLittleBit() == true); \
103 MOZ_ASSERT(val.LoadLargeAndInCharge() == int_max); \
104 val.StoreHappyLittleBit(false); \
105 MOZ_ASSERT(val.LoadHappyLittleBit() == false); \
106 MOZ_ASSERT(val.LoadLargeAndInCharge() == int_max); \
107 val.StoreLargeAndInCharge(int_max); \
108 MOZ_ASSERT(val.LoadHappyLittleBit() == false); \
109 MOZ_ASSERT(val.LoadLargeAndInCharge() == int_max); \
112 #define GENERATE_TEST_LOPSIDED(aSize) \
113 struct LopsidedA##aSize { \
114 MOZ_ATOMIC_BITFIELDS(mAtomicFields, aSize, \
115 ((bool, HappyLittleBit, 1), \
116 (uint##aSize##_t, LargeAndInCharge, ((aSize)-1)))) \
117 }; \
118 struct LopsidedB##aSize { \
119 MOZ_ATOMIC_BITFIELDS(mAtomicFields, aSize, \
120 ((uint##aSize##_t, LargeAndInCharge, ((aSize)-1)), \
121 (bool, HappyLittleBit, 1))) \
122 }; \
123 GENERATE_TEST_LOPSIDED_FUNC(A, aSize); \
124 GENERATE_TEST_LOPSIDED_FUNC(B, aSize);
126 #define TEST_LOPSIDED(aSize) \
127 TestLopsidedA##aSize(); \
128 TestLopsidedB##aSize();
130 // ==================== generate and run the tests ======================
132 // There's an unknown bug in clang-cl-9 (used for win64-ccov) that makes
133 // generating these with the TIMES_N macro not work. So these are written out
134 // explicitly to unbork CI.
135 struct JammedWithFlags8 {
136 MOZ_ATOMIC_BITFIELDS(mAtomicFields, 8,
137 ((bool, Flag1, 1), (bool, Flag2, 1), (bool, Flag3, 1),
138 (bool, Flag4, 1), (bool, Flag5, 1), (bool, Flag6, 1),
139 (bool, Flag7, 1), (bool, Flag8, 1)))
142 struct JammedWithFlags16 {
143 MOZ_ATOMIC_BITFIELDS(mAtomicFields, 16,
144 ((bool, Flag1, 1), (bool, Flag2, 1), (bool, Flag3, 1),
145 (bool, Flag4, 1), (bool, Flag5, 1), (bool, Flag6, 1),
146 (bool, Flag7, 1), (bool, Flag8, 1), (bool, Flag9, 1),
147 (bool, Flag10, 1), (bool, Flag11, 1), (bool, Flag12, 1),
148 (bool, Flag13, 1), (bool, Flag14, 1), (bool, Flag15, 1),
149 (bool, Flag16, 1)))
152 struct JammedWithFlags32 {
153 MOZ_ATOMIC_BITFIELDS(mAtomicFields, 32,
154 ((bool, Flag1, 1), (bool, Flag2, 1), (bool, Flag3, 1),
155 (bool, Flag4, 1), (bool, Flag5, 1), (bool, Flag6, 1),
156 (bool, Flag7, 1), (bool, Flag8, 1), (bool, Flag9, 1),
157 (bool, Flag10, 1), (bool, Flag11, 1), (bool, Flag12, 1),
158 (bool, Flag13, 1), (bool, Flag14, 1), (bool, Flag15, 1),
159 (bool, Flag16, 1), (bool, Flag17, 1), (bool, Flag18, 1),
160 (bool, Flag19, 1), (bool, Flag20, 1), (bool, Flag21, 1),
161 (bool, Flag22, 1), (bool, Flag23, 1), (bool, Flag24, 1),
162 (bool, Flag25, 1), (bool, Flag26, 1), (bool, Flag27, 1),
163 (bool, Flag28, 1), (bool, Flag29, 1), (bool, Flag30, 1),
164 (bool, Flag31, 1), (bool, Flag32, 1)))
167 GENERATE_TEST_JAMMED_WITH_FLAGS(8)
168 GENERATE_TEST_JAMMED_WITH_FLAGS(16)
169 GENERATE_TEST_JAMMED_WITH_FLAGS(32)
170 // MOZ_FOR_EACH_64 doesn't exist :(
172 GENERATE_TEST_LOPSIDED(8)
173 GENERATE_TEST_LOPSIDED(16)
174 GENERATE_TEST_LOPSIDED(32)
175 GENERATE_TEST_LOPSIDED(64)
177 int main() {
178 TestDocumentationExample();
180 TEST_JAMMED_WITH_FLAGS(8);
181 TEST_JAMMED_WITH_FLAGS(16);
182 TEST_JAMMED_WITH_FLAGS(32);
184 TEST_LOPSIDED(8);
185 TEST_LOPSIDED(16);
186 TEST_LOPSIDED(32);
187 TEST_LOPSIDED(64);
188 return 0;