Skip to content

Commit 4b0244b

Browse files
committed
Test Atomic<T> with user T
1 parent 9d58bef commit 4b0244b

File tree

1 file changed

+82
-13
lines changed

1 file changed

+82
-13
lines changed

TESTS/mbed_platform/atomic/main.cpp

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ static inline long add_iterations(A &a)
3939
}
4040

4141
template <typename A>
42-
struct add_incrementer
43-
{
42+
struct add_incrementer {
4443
static void op(A *ptr)
4544
{
4645
for (long i = add_iterations(*ptr); i > 0; i--) {
@@ -50,8 +49,7 @@ struct add_incrementer
5049
};
5150

5251
template <typename A>
53-
struct add_release_incrementer
54-
{
52+
struct add_release_incrementer {
5553
static void op(A *ptr)
5654
{
5755
for (long i = add_iterations(*ptr); i > 0; i--) {
@@ -61,8 +59,7 @@ struct add_release_incrementer
6159
};
6260

6361
template <typename A>
64-
struct sub_incrementer
65-
{
62+
struct sub_incrementer {
6663
static void op(A *ptr)
6764
{
6865
for (long i = add_iterations(*ptr); i > 0; i--) {
@@ -72,8 +69,7 @@ struct sub_incrementer
7269
};
7370

7471
template <typename A>
75-
struct bitops_incrementer
76-
{
72+
struct bitops_incrementer {
7773
static void op(A *ptr)
7874
{
7975
for (long i = add_iterations(*ptr); i > 0; i--) {
@@ -85,8 +81,7 @@ struct bitops_incrementer
8581
};
8682

8783
template <typename A>
88-
struct weak_incrementer
89-
{
84+
struct weak_incrementer {
9085
static void op(A *ptr)
9186
{
9287
for (long i = add_iterations(*ptr); i > 0; i--) {
@@ -98,8 +93,7 @@ struct weak_incrementer
9893
};
9994

10095
template <typename A>
101-
struct strong_incrementer
102-
{
96+
struct strong_incrementer {
10397
static void op(A *ptr)
10498
{
10599
for (long i = add_iterations(*ptr); i > 0; i--) {
@@ -164,6 +158,79 @@ void test_atomic_add()
164158
TEST_ASSERT_EQUAL(T(ADD_UNLOCKED_ITERATIONS), data.nonatomic2);
165159
}
166160

161+
// This should fit into a uint32_t container, and there
162+
// will be 1 byte of padding to ignore.
163+
struct small {
164+
uint8_t a;
165+
uint8_t b;
166+
uint8_t c;
167+
};
168+
169+
// An 11-byte weird structure. Should work with critical sections.
170+
struct large {
171+
uint8_t a;
172+
uint8_t b;
173+
uint8_t c;
174+
uint8_t dummy[8];
175+
};
176+
177+
template<typename A>
178+
void struct_incrementer_a(A *data)
179+
{
180+
for (long i = add_iterations(*data); i > 0; i--) {
181+
typename A::value_type curval = *data, newval;
182+
do {
183+
newval = curval;
184+
newval.a++;
185+
} while (!data->compare_exchange_weak(curval, newval));
186+
}
187+
}
188+
189+
template<typename A>
190+
void struct_incrementer_b(A *data)
191+
{
192+
for (long i = add_iterations(*data); i > 0; i--) {
193+
typename A::value_type curval = *data, newval;
194+
do {
195+
newval = curval;
196+
newval.b++;
197+
} while (!data->compare_exchange_weak(curval, newval));
198+
}
199+
}
200+
201+
template<typename T, size_t N>
202+
void test_atomic_struct()
203+
{
204+
TEST_ASSERT_EQUAL(N, sizeof(Atomic<T>));
205+
206+
// Small structures don't have value constructor implemented;
207+
Atomic<T> data;
208+
atomic_init(&data, T{0, 0, 0});
209+
210+
Thread t1(osPriorityNormal, THREAD_STACK);
211+
Thread t2(osPriorityNormal, THREAD_STACK);
212+
213+
TEST_ASSERT_EQUAL(osOK, t1.start(callback(struct_incrementer_a<Atomic<T> >, &data)));
214+
TEST_ASSERT_EQUAL(osOK, t2.start(callback(struct_incrementer_b<Atomic<T> >, &data)));
215+
216+
for (long i = add_iterations(data); i > 0; i--) {
217+
T curval = data, newval;
218+
do {
219+
newval = curval;
220+
newval.c++;
221+
} while (!data.compare_exchange_weak(curval, newval));
222+
}
223+
224+
t1.join();
225+
t2.join();
226+
227+
T final_val = data;
228+
229+
TEST_ASSERT_EQUAL(uint8_t(add_iterations(data)), final_val.a);
230+
TEST_ASSERT_EQUAL(uint8_t(add_iterations(data)), final_val.b);
231+
TEST_ASSERT_EQUAL(uint8_t(add_iterations(data)), final_val.c);
232+
}
233+
167234
} // namespace
168235

169236
utest::v1::status_t test_setup(const size_t number_of_cases)
@@ -197,7 +264,9 @@ Case cases[] = {
197264
Case("Test atomic compare exchange strong 8-bit", test_atomic_add<uint8_t, strong_incrementer>),
198265
Case("Test atomic compare exchange strong 16-bit", test_atomic_add<uint16_t, strong_incrementer>),
199266
Case("Test atomic compare exchange strong 32-bit", test_atomic_add<uint32_t, strong_incrementer>),
200-
Case("Test atomic compare exchange strong 64-bit", test_atomic_add<uint64_t, strong_incrementer>)
267+
Case("Test atomic compare exchange strong 64-bit", test_atomic_add<uint64_t, strong_incrementer>),
268+
Case("Test small atomic custom structure", test_atomic_struct<small, 4>),
269+
Case("Test large atomic custom structure", test_atomic_struct<large, 11>)
201270
};
202271

203272
utest::v1::Specification specification(test_setup, cases);

0 commit comments

Comments
 (0)