@@ -39,8 +39,7 @@ static inline long add_iterations(A &a)
3939}
4040
4141template <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
5251template <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
6361template <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
7471template <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
8783template <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
10095template <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
169236utest::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
203272utest::v1::Specification specification (test_setup, cases);
0 commit comments