@@ -139,6 +139,78 @@ void test_atomic_add()
139139 TEST_ASSERT_EQUAL (T (ADD_ITERATIONS), data.nonatomic2 );
140140}
141141
142+ // This should fit into a uint32_t container, and there
143+ // will be 1 byte of padding to ignore.
144+ struct small {
145+ uint8_t a;
146+ uint8_t b;
147+ uint8_t c;
148+ };
149+
150+ // An 11-byte weird structure. Should work with critical sections.
151+ struct large {
152+ uint8_t a;
153+ uint8_t b;
154+ uint8_t c;
155+ uint8_t dummy[8 ];
156+ };
157+
158+ template <typename A>
159+ void struct_incrementer_a (A *data)
160+ {
161+ for (long i = ADD_ITERATIONS; i > 0 ; i--) {
162+ typename A::value_type curval = *data, newval;
163+ do {
164+ newval = curval;
165+ newval.a ++;
166+ } while (!data->compare_exchange_weak (curval, newval));
167+ }
168+ }
169+
170+ template <typename A>
171+ void struct_incrementer_b (A *data)
172+ {
173+ for (long i = ADD_ITERATIONS; i > 0 ; i--) {
174+ typename A::value_type curval = *data, newval;
175+ do {
176+ newval = curval;
177+ newval.b ++;
178+ } while (!data->compare_exchange_weak (curval, newval));
179+ }
180+ }
181+
182+ template <typename T, size_t N>
183+ void test_atomic_struct ()
184+ {
185+ TEST_ASSERT_EQUAL (N, sizeof (Atomic<T>));
186+
187+ T init = { 0 , 0 , 0 };
188+ Atomic<T> data (init);
189+
190+ Thread t1 (osPriorityNormal, THREAD_STACK);
191+ Thread t2 (osPriorityNormal, THREAD_STACK);
192+
193+ TEST_ASSERT_EQUAL (osOK, t1.start (callback (struct_incrementer_a<Atomic<T> >, &data)));
194+ TEST_ASSERT_EQUAL (osOK, t2.start (callback (struct_incrementer_b<Atomic<T> >, &data)));
195+
196+ for (long i = ADD_ITERATIONS; i > 0 ; i--) {
197+ T curval = data, newval;
198+ do {
199+ newval = curval;
200+ newval.c ++;
201+ } while (!data.compare_exchange_weak (curval, newval));
202+ }
203+
204+ t1.join ();
205+ t2.join ();
206+
207+ T final_val = data;
208+
209+ TEST_ASSERT_EQUAL (uint8_t (ADD_ITERATIONS), final_val.a );
210+ TEST_ASSERT_EQUAL (uint8_t (ADD_ITERATIONS), final_val.b );
211+ TEST_ASSERT_EQUAL (uint8_t (ADD_ITERATIONS), final_val.c );
212+ }
213+
142214} // namespace
143215
144216utest::v1::status_t test_setup (const size_t number_of_cases)
@@ -172,7 +244,9 @@ Case cases[] = {
172244 Case (" Test atomic compare exchange strong 8-bit" , test_atomic_add<uint8_t , strong_incrementer>),
173245 Case (" Test atomic compare exchange strong 16-bit" , test_atomic_add<uint16_t , strong_incrementer>),
174246 Case (" Test atomic compare exchange strong 32-bit" , test_atomic_add<uint32_t , strong_incrementer>),
175- Case (" Test atomic compare exchange strong 64-bit" , test_atomic_add<uint64_t , strong_incrementer>)
247+ Case (" Test atomic compare exchange strong 64-bit" , test_atomic_add<uint64_t , strong_incrementer>),
248+ Case (" Test small atomic custom structure" , test_atomic_struct<small, 4 >),
249+ Case (" Test large atomic custom structure" , test_atomic_struct<large, 11 >)
176250};
177251
178252utest::v1::Specification specification (test_setup, cases);
0 commit comments