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