@@ -39,8 +39,7 @@ static inline long add_iterations(A &a)
39
39
}
40
40
41
41
template <typename A>
42
- struct add_incrementer
43
- {
42
+ struct add_incrementer {
44
43
static void op (A *ptr)
45
44
{
46
45
for (long i = add_iterations (*ptr); i > 0 ; i--) {
@@ -50,8 +49,7 @@ struct add_incrementer
50
49
};
51
50
52
51
template <typename A>
53
- struct add_release_incrementer
54
- {
52
+ struct add_release_incrementer {
55
53
static void op (A *ptr)
56
54
{
57
55
for (long i = add_iterations (*ptr); i > 0 ; i--) {
@@ -61,8 +59,7 @@ struct add_release_incrementer
61
59
};
62
60
63
61
template <typename A>
64
- struct sub_incrementer
65
- {
62
+ struct sub_incrementer {
66
63
static void op (A *ptr)
67
64
{
68
65
for (long i = add_iterations (*ptr); i > 0 ; i--) {
@@ -72,8 +69,7 @@ struct sub_incrementer
72
69
};
73
70
74
71
template <typename A>
75
- struct bitops_incrementer
76
- {
72
+ struct bitops_incrementer {
77
73
static void op (A *ptr)
78
74
{
79
75
for (long i = add_iterations (*ptr); i > 0 ; i--) {
@@ -85,8 +81,7 @@ struct bitops_incrementer
85
81
};
86
82
87
83
template <typename A>
88
- struct weak_incrementer
89
- {
84
+ struct weak_incrementer {
90
85
static void op (A *ptr)
91
86
{
92
87
for (long i = add_iterations (*ptr); i > 0 ; i--) {
@@ -98,8 +93,7 @@ struct weak_incrementer
98
93
};
99
94
100
95
template <typename A>
101
- struct strong_incrementer
102
- {
96
+ struct strong_incrementer {
103
97
static void op (A *ptr)
104
98
{
105
99
for (long i = add_iterations (*ptr); i > 0 ; i--) {
@@ -164,6 +158,79 @@ void test_atomic_add()
164
158
TEST_ASSERT_EQUAL (T (ADD_UNLOCKED_ITERATIONS), data.nonatomic2 );
165
159
}
166
160
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
+
167
234
} // namespace
168
235
169
236
utest::v1::status_t test_setup (const size_t number_of_cases)
@@ -197,7 +264,9 @@ Case cases[] = {
197
264
Case (" Test atomic compare exchange strong 8-bit" , test_atomic_add<uint8_t , strong_incrementer>),
198
265
Case (" Test atomic compare exchange strong 16-bit" , test_atomic_add<uint16_t , strong_incrementer>),
199
266
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 >)
201
270
};
202
271
203
272
utest::v1::Specification specification (test_setup, cases);
0 commit comments