@@ -12,51 +12,62 @@ using namespace utest::v1;
12
12
13
13
#define TEST_STACK_SIZE 512
14
14
15
- #define TEST_ONE_SEC_MS (1000 )
16
- #define TEST_HALF_SEC_MS (500 )
17
- #define TEST_HALF_SEC_US (500000 )
18
- #define TEST_ONE_MS_US (1000 )
19
-
20
- #define THREAD_DELAY 50
21
- #define SIGNALS_TO_EMIT 100
15
+ #define TEST_LONG_DELAY 20
16
+ #define TEST_DELAY 10
17
+ #define SIGNALS_TO_EMIT 100
22
18
23
19
Mutex stdio_mutex;
24
20
25
21
volatile int change_counter = 0 ;
26
22
volatile bool changing_counter = false ;
27
23
volatile bool mutex_defect = false ;
28
24
29
- bool manipulate_protected_zone (const int thread_delay) {
25
+ bool manipulate_protected_zone (const int thread_delay)
26
+ {
30
27
bool result = true ;
31
28
32
29
osStatus stat = stdio_mutex.lock ();
33
- TEST_ASSERT_EQUAL (stat, osOK);
30
+ TEST_ASSERT_EQUAL (osOK, stat);
31
+
32
+ core_util_critical_section_enter ();
34
33
if (changing_counter == true ) {
35
34
result = false ;
36
35
mutex_defect = true ;
37
36
}
38
37
changing_counter = true ;
39
38
40
39
change_counter++;
40
+ core_util_critical_section_exit ();
41
+
41
42
Thread::wait (thread_delay);
42
43
44
+ core_util_critical_section_enter ();
43
45
changing_counter = false ;
46
+ core_util_critical_section_exit ();
47
+
44
48
stat = stdio_mutex.unlock ();
45
- TEST_ASSERT_EQUAL (stat, osOK );
49
+ TEST_ASSERT_EQUAL (osOK, stat );
46
50
return result;
47
51
}
48
52
49
- void test_thread (int const *thread_delay) {
53
+ void test_thread (int const *thread_delay)
54
+ {
50
55
while (true ) {
51
56
manipulate_protected_zone (*thread_delay);
52
57
}
53
58
}
54
59
60
+ /* * Test multiple thread
61
+
62
+ Given 3 threads started with different delays and a section protected with a mutex
63
+ when each thread runs it tries to lock the mutex
64
+ then no more than one thread should be able to access protected region
65
+ */
55
66
void test_multiple_threads (void )
56
67
{
57
- const int t1_delay = THREAD_DELAY * 1 ;
58
- const int t2_delay = THREAD_DELAY * 2 ;
59
- const int t3_delay = THREAD_DELAY * 3 ;
68
+ const int t1_delay = TEST_DELAY * 1 ;
69
+ const int t2_delay = TEST_DELAY * 2 ;
70
+ const int t3_delay = TEST_DELAY * 3 ;
60
71
61
72
Thread t2 (osPriorityNormal, TEST_STACK_SIZE);
62
73
Thread t3 (osPriorityNormal, TEST_STACK_SIZE);
@@ -69,34 +80,51 @@ void test_multiple_threads(void)
69
80
Thread::wait (t1_delay);
70
81
manipulate_protected_zone (t1_delay);
71
82
83
+ core_util_critical_section_enter ();
72
84
if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true ) {
85
+ core_util_critical_section_exit ();
73
86
t2.terminate ();
74
87
t3.terminate ();
75
88
break ;
76
89
}
90
+ core_util_critical_section_exit ();
77
91
}
78
92
79
- TEST_ASSERT_EQUAL (mutex_defect, false );
93
+ TEST_ASSERT_EQUAL (false , mutex_defect );
80
94
}
81
95
82
96
void test_dual_thread_nolock_lock_thread (Mutex *mutex)
83
97
{
84
- bool stat_b = mutex->trylock ( );
85
- TEST_ASSERT_EQUAL (stat_b, true );
98
+ osStatus stat = mutex->lock (osWaitForever );
99
+ TEST_ASSERT_EQUAL (osOK, stat );
86
100
87
- osStatus stat = mutex->unlock ();
88
- TEST_ASSERT_EQUAL (stat, osOK );
101
+ stat = mutex->unlock ();
102
+ TEST_ASSERT_EQUAL (osOK, stat );
89
103
}
90
104
91
105
void test_dual_thread_nolock_trylock_thread (Mutex *mutex)
92
106
{
93
107
bool stat_b = mutex->trylock ();
94
- TEST_ASSERT_EQUAL (stat_b, true );
108
+ TEST_ASSERT_EQUAL (true , stat_b );
95
109
96
110
osStatus stat = mutex->unlock ();
97
- TEST_ASSERT_EQUAL (stat, osOK );
111
+ TEST_ASSERT_EQUAL (osOK, stat );
98
112
}
99
113
114
+ /* * Test dual thread no-lock
115
+
116
+ Test dual thread second thread lock
117
+ Given two threads A & B and a mutex
118
+ When thread A creates a mutex and starts thread B
119
+ and thread B calls @a lock and @a unlock
120
+ Then returned statuses are osOK
121
+
122
+ Test dual thread second thread trylock
123
+ Given two threads A & B and a mutex
124
+ When thread A creates a mutex and starts thread B
125
+ and thread B calls @a trylock and @a unlock
126
+ Then returned statuses are true and osOK
127
+ */
100
128
template <void (*F)(Mutex *)>
101
129
void test_dual_thread_nolock (void )
102
130
{
@@ -105,47 +133,70 @@ void test_dual_thread_nolock(void)
105
133
106
134
thread.start (callback (F, &mutex));
107
135
108
- wait_us (TEST_HALF_SEC_MS );
136
+ wait_ms (TEST_DELAY );
109
137
}
110
138
111
139
void test_dual_thread_lock_unlock_thread (Mutex *mutex)
112
140
{
113
141
osStatus stat = mutex->lock (osWaitForever);
114
- TEST_ASSERT_EQUAL (stat, osOK );
142
+ TEST_ASSERT_EQUAL (osOK, stat );
115
143
}
116
144
145
+ /* * Test dual thread lock unlock
146
+
147
+ Given two threads and a lock
148
+ When thread A locks the lock and starts thread B
149
+ and thread B calls @a lock on the mutex
150
+ Then thread B waits for thread A to unlock the lock
151
+ When thread A calls @a unlock on the mutex
152
+ Then thread B acquires the lock
153
+ */
117
154
void test_dual_thread_lock_unlock (void )
118
155
{
119
156
Mutex mutex;
120
157
osStatus stat;
121
158
Thread thread (osPriorityNormal, TEST_STACK_SIZE);
122
159
123
160
stat = mutex.lock ();
124
- TEST_ASSERT_EQUAL (stat, osOK );
161
+ TEST_ASSERT_EQUAL (osOK, stat );
125
162
126
163
thread.start (callback (test_dual_thread_lock_unlock_thread, &mutex));
127
164
128
165
stat = mutex.unlock ();
129
- TEST_ASSERT_EQUAL (stat, osOK );
166
+ TEST_ASSERT_EQUAL (osOK, stat );
130
167
131
- wait_us (TEST_HALF_SEC_MS );
168
+ wait_ms (TEST_DELAY );
132
169
}
133
170
134
171
void test_dual_thread_lock_trylock_thread (Mutex *mutex)
135
172
{
136
173
bool stat = mutex->trylock ();
137
- TEST_ASSERT_EQUAL (stat, false );
174
+ TEST_ASSERT_EQUAL (false , stat );
138
175
}
139
176
140
177
void test_dual_thread_lock_lock_thread (Mutex *mutex)
141
178
{
142
179
uint32_t start = us_ticker_read ();
143
180
144
- osStatus stat = mutex->lock (TEST_HALF_SEC_MS );
145
- TEST_ASSERT_EQUAL (stat, osErrorTimeout );
146
- TEST_ASSERT_UINT32_WITHIN (TEST_ONE_MS_US, TEST_HALF_SEC_US , us_ticker_read () - start);
181
+ osStatus stat = mutex->lock (TEST_DELAY );
182
+ TEST_ASSERT_EQUAL (osErrorTimeout, stat );
183
+ TEST_ASSERT_UINT32_WITHIN (5000 , TEST_DELAY* 1000 , us_ticker_read () - start);
147
184
}
148
185
186
+ /* * Test dual thread lock
187
+
188
+ Test dual thread lock locked
189
+ Given a mutex and two threads A & B
190
+ When thread A calls @a lock and starts thread B
191
+ and thread B calls @a lock with 500ms timeout
192
+ Then thread B waits 500ms and timeouts
193
+
194
+ Test dual thread trylock locked
195
+ Given a mutex and two threads A & B
196
+ When thread A calls @a lock and starts thread B
197
+ Then thread B calls @a trylock
198
+ and thread B fails to acquire the lock
199
+ */
149
200
template <void (*F)(Mutex *)>
150
201
void test_dual_thread_lock (void )
151
202
{
@@ -154,59 +205,78 @@ void test_dual_thread_lock(void)
154
205
Thread thread (osPriorityNormal, TEST_STACK_SIZE);
155
206
156
207
stat = mutex.lock ();
157
- TEST_ASSERT_EQUAL (stat, osOK );
208
+ TEST_ASSERT_EQUAL (osOK, stat );
158
209
159
210
thread.start (callback (F, &mutex));
160
211
161
- wait_us (TEST_ONE_SEC_MS );
212
+ wait_ms (TEST_LONG_DELAY );
162
213
163
214
stat = mutex.unlock ();
164
- TEST_ASSERT_EQUAL (stat, osOK );
215
+ TEST_ASSERT_EQUAL (osOK, stat );
165
216
}
166
217
218
+ /* * Test single thread lock recursive
219
+
220
+ Given a mutex and a single running thread
221
+ When thread calls @a lock twice and @a unlock twice on the mutex
222
+ Then the returned statuses are osOK
223
+ */
167
224
void test_single_thread_lock_recursive (void )
168
225
{
169
226
Mutex mutex;
170
227
osStatus stat;
171
228
172
229
stat = mutex.lock ();
173
- TEST_ASSERT_EQUAL (stat, osOK );
230
+ TEST_ASSERT_EQUAL (osOK, stat );
174
231
175
232
stat = mutex.lock ();
176
- TEST_ASSERT_EQUAL (stat, osOK );
233
+ TEST_ASSERT_EQUAL (osOK, stat );
177
234
178
235
stat = mutex.unlock ();
179
- TEST_ASSERT_EQUAL (stat, osOK );
236
+ TEST_ASSERT_EQUAL (osOK, stat );
180
237
181
238
stat = mutex.unlock ();
182
- TEST_ASSERT_EQUAL (stat, osOK );
239
+ TEST_ASSERT_EQUAL (osOK, stat );
183
240
}
184
241
242
+ /* * Test single thread trylock
243
+
244
+ Given a mutex and a single running thread
245
+ When thread calls @a trylock and @a unlock on the mutex
246
+ Then the returned statuses are osOK
247
+ */
185
248
void test_single_thread_trylock (void )
186
249
{
187
250
Mutex mutex;
188
251
189
252
bool stat_b = mutex.trylock ();
190
- TEST_ASSERT_EQUAL (stat_b, true );
253
+ TEST_ASSERT_EQUAL (true , stat_b );
191
254
192
255
osStatus stat = mutex.unlock ();
193
- TEST_ASSERT_EQUAL (stat, osOK );
256
+ TEST_ASSERT_EQUAL (osOK, stat );
194
257
}
195
258
259
+ /* * Test single thread lock
260
+
261
+ Given a mutex and a single running thread
262
+ When thread calls @a lock and @a unlock on the mutex
263
+ Then the returned statuses are osOK
264
+ */
196
265
void test_single_thread_lock (void )
197
266
{
198
267
Mutex mutex;
199
268
osStatus stat;
200
269
201
270
stat = mutex.lock ();
202
- TEST_ASSERT_EQUAL (stat, osOK );
271
+ TEST_ASSERT_EQUAL (osOK, stat );
203
272
204
273
stat = mutex.unlock ();
205
- TEST_ASSERT_EQUAL (stat, osOK );
274
+ TEST_ASSERT_EQUAL (osOK, stat );
206
275
}
207
276
208
- utest::v1::status_t test_setup (const size_t number_of_cases) {
209
- GREENTEA_SETUP (15 , " default_auto" );
277
+ utest::v1::status_t test_setup (const size_t number_of_cases)
278
+ {
279
+ GREENTEA_SETUP (10 , " default_auto" );
210
280
return verbose_test_setup_handler (number_of_cases);
211
281
}
212
282
@@ -224,6 +294,7 @@ Case cases[] = {
224
294
225
295
Specification specification (test_setup, cases);
226
296
227
- int main () {
297
+ int main ()
298
+ {
228
299
return !Harness::run (specification);
229
300
}
0 commit comments