/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h"
#include "mozilla/AtomicBitfields.h"
// This is a big macro mess, so let's summarize what's in here right up front:
//
// |TestDocumentationExample| is intended to be a copy-paste of the example
// in the macro's documentation, to make sure it's correct.
//
//
// |TestJammedWithFlags| tests using every bit of the type for bool flags.
// 64-bit isn't tested due to macro limitations.
//
//
// |TestLopsided| tests an instance with the following configuration:
//
// * a 1-bit boolean
// * an (N-1)-bit uintN_t
//
// It tests both orderings of these fields.
//
// Hopefully these are enough to cover all the nasty boundary conditions
// (that still compile).
// ==================== TestDocumentationExample ========================
struct MyType {
MOZ_ATOMIC_BITFIELDS(mAtomicFields,
8 ,
((
bool , IsDownloaded,
1 ), (uint32_t, SomeData,
2 ),
(uint8_t, OtherData,
5 )))
int32_t aNormalInteger;
explicit MyType(uint32_t aSomeData) : aNormalInteger(
7 ) {
StoreSomeData(aSomeData);
// Other bitfields were already default initialized to 0/false
}
};
void TestDocumentationExample() {
MyType val(
3 );
if (!val.LoadIsDownloaded()) {
val.StoreOtherData(
2 );
val.StoreIsDownloaded(true);
}
}
// ====================== TestJammedWithFlags =========================
#define TIMES_8(aFunc, aSeparator, aArgs) \
MOZ_FOR_EACH_SEPARATED(aFunc, aSeparator, aArgs, (
1 ,
2 ,
3 ,
4 ,
5 ,
6 ,
7 ,
8 ))
#define TIMES_16(aFunc, aSeparator, aArgs) \
MOZ_FOR_EACH_SEPARATED( \
aFunc, aSeparator, aArgs, \
(
1 ,
2 ,
3 ,
4 ,
5 ,
6 ,
7 ,
8 ,
9 ,
10 ,
11 ,
12 ,
13 ,
14 ,
15 ,
16 ))
#define TIMES_32(aFunc, aSeparator, aArgs) \
MOZ_FOR_EACH_SEPARATED( \
aFunc, aSeparator, aArgs, \
(
1 ,
2 ,
3 ,
4 ,
5 ,
6 ,
7 ,
8 ,
9 ,
10 ,
11 ,
12 ,
13 ,
14 ,
15 ,
16 ,
17 ,
18 ,
19 ,
20 , \
21 ,
22 ,
23 ,
24 ,
25 ,
26 ,
27 ,
28 ,
29 ,
30 ,
31 ,
32 ))
#define CHECK_BOOL(aIndex) \
MOZ_RELEASE_ASSERT(val.LoadFlag
## aIndex() ==
false ); \
val.StoreFlag
## aIndex(true); \
MOZ_RELEASE_ASSERT(val.LoadFlag
## aIndex() == true); \
val.StoreFlag
## aIndex(
false ); \
MOZ_RELEASE_ASSERT(val.LoadFlag
## aIndex() ==
false );
#define GENERATE_TEST_JAMMED_WITH_FLAGS(aSize) \
void TestJammedWithFlags
## aSize() { \
JammedWithFlags
## aSize val; \
TIMES_
## aSize(CHECK_BOOL, (;), ()); \
}
#define TEST_JAMMED_WITH_FLAGS(aSize) TestJammedWithFlags
## aSize();
// ========================= TestLopsided ===========================
#define GENERATE_TEST_LOPSIDED_FUNC(aSide, aSize) \
void TestLopsided
## aSide
## aSize() { \
Lopsided
## aSide
## aSize val; \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() ==
false ); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() ==
0 ); \
val.StoreHappyLittleBit(true); \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() == true); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() ==
0 ); \
val.StoreLargeAndInCharge(
1 ); \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() == true); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() ==
1 ); \
val.StoreLargeAndInCharge(
0 ); \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() == true); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() ==
0 ); \
uint
## aSize
## _t size = aSize; \
uint
## aSize
## _t int_max = (~(
1 ull << (size -
1 ))) -
1 ; \
val.StoreLargeAndInCharge(int_max); \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() == true); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() == int_max); \
val.StoreHappyLittleBit(
false ); \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() ==
false ); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() == int_max); \
val.StoreLargeAndInCharge(int_max); \
MOZ_RELEASE_ASSERT(val.LoadHappyLittleBit() ==
false ); \
MOZ_RELEASE_ASSERT(val.LoadLargeAndInCharge() == int_max); \
}
#define GENERATE_TEST_LOPSIDED(aSize) \
struct LopsidedA
## aSize { \
MOZ_ATOMIC_BITFIELDS(mAtomicFields, aSize, \
((
bool , HappyLittleBit,
1 ), \
(uint
## aSize
## _t, LargeAndInCharge, ((aSize) -
1 )))) \
}; \
struct LopsidedB
## aSize { \
MOZ_ATOMIC_BITFIELDS(mAtomicFields, aSize, \
((uint
## aSize
## _t, LargeAndInCharge, ((aSize) -
1 )), \
(
bool , HappyLittleBit,
1 ))) \
}; \
GENERATE_TEST_LOPSIDED_FUNC(A, aSize); \
GENERATE_TEST_LOPSIDED_FUNC(B, aSize);
#define TEST_LOPSIDED(aSize) \
TestLopsidedA
## aSize(); \
TestLopsidedB
## aSize();
// ==================== generate and run the tests ======================
// There's an unknown bug in clang-cl-9 (used for win64-ccov) that makes
// generating these with the TIMES_N macro not work. So these are written out
// explicitly to unbork CI.
struct JammedWithFlags8 {
MOZ_ATOMIC_BITFIELDS(mAtomicFields,
8 ,
((
bool , Flag1,
1 ), (
bool , Flag2,
1 ), (
bool , Flag3,
1 ),
(
bool , Flag4,
1 ), (
bool , Flag5,
1 ), (
bool , Flag6,
1 ),
(
bool , Flag7,
1 ), (
bool , Flag8,
1 )))
};
struct JammedWithFlags16 {
MOZ_ATOMIC_BITFIELDS(mAtomicFields,
16 ,
((
bool , Flag1,
1 ), (
bool , Flag2,
1 ), (
bool , Flag3,
1 ),
(
bool , Flag4,
1 ), (
bool , Flag5,
1 ), (
bool , Flag6,
1 ),
(
bool , Flag7,
1 ), (
bool , Flag8,
1 ), (
bool , Flag9,
1 ),
(
bool , Flag10,
1 ), (
bool , Flag11,
1 ), (
bool , Flag12,
1 ),
(
bool , Flag13,
1 ), (
bool , Flag14,
1 ), (
bool , Flag15,
1 ),
(
bool , Flag16,
1 )))
};
struct JammedWithFlags32 {
MOZ_ATOMIC_BITFIELDS(mAtomicFields,
32 ,
((
bool , Flag1,
1 ), (
bool , Flag2,
1 ), (
bool , Flag3,
1 ),
(
bool , Flag4,
1 ), (
bool , Flag5,
1 ), (
bool , Flag6,
1 ),
(
bool , Flag7,
1 ), (
bool , Flag8,
1 ), (
bool , Flag9,
1 ),
(
bool , Flag10,
1 ), (
bool , Flag11,
1 ), (
bool , Flag12,
1 ),
(
bool , Flag13,
1 ), (
bool , Flag14,
1 ), (
bool , Flag15,
1 ),
(
bool , Flag16,
1 ), (
bool , Flag17,
1 ), (
bool , Flag18,
1 ),
(
bool , Flag19,
1 ), (
bool , Flag20,
1 ), (
bool , Flag21,
1 ),
(
bool , Flag22,
1 ), (
bool , Flag23,
1 ), (
bool , Flag24,
1 ),
(
bool , Flag25,
1 ), (
bool , Flag26,
1 ), (
bool , Flag27,
1 ),
(
bool , Flag28,
1 ), (
bool , Flag29,
1 ), (
bool , Flag30,
1 ),
(
bool , Flag31,
1 ), (
bool , Flag32,
1 )))
};
GENERATE_TEST_JAMMED_WITH_FLAGS(
8 )
GENERATE_TEST_JAMMED_WITH_FLAGS(
16 )
GENERATE_TEST_JAMMED_WITH_FLAGS(
32 )
// MOZ_FOR_EACH_64 doesn't exist :(
GENERATE_TEST_LOPSIDED(
8 )
GENERATE_TEST_LOPSIDED(
16 )
GENERATE_TEST_LOPSIDED(
32 )
GENERATE_TEST_LOPSIDED(
64 )
int main() {
TestDocumentationExample();
TEST_JAMMED_WITH_FLAGS(
8 );
TEST_JAMMED_WITH_FLAGS(
16 );
TEST_JAMMED_WITH_FLAGS(
32 );
TEST_LOPSIDED(
8 );
TEST_LOPSIDED(
16 );
TEST_LOPSIDED(
32 );
TEST_LOPSIDED(
64 );
return 0 ;
}
Messung V0.5 in Prozent C=95 H=97 G=95
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland