14
14
* See the License for the specific language governing permissions and
15
15
* limitations under the License.
16
16
*/
17
- #if defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)
18
- #error [NOT_SUPPORTED] Semaphore test cases require RTOS with multithread to run
19
- #else
20
-
21
17
#if !DEVICE_USTICKER
22
18
#error [NOT_SUPPORTED] UsTicker need to be enabled for this test.
23
19
#else
30
26
31
27
using namespace utest ::v1;
32
28
29
+ struct test_data {
30
+ Semaphore *sem;
31
+ uint32_t data;
32
+ };
33
+
34
+ #if defined(MBED_CONF_RTOS_PRESENT)
33
35
#define THREAD_DELAY 30
34
36
#define SEMAPHORE_SLOTS 2
35
37
#define SEM_CHANGES 100
@@ -90,12 +92,7 @@ void test_multi()
90
92
}
91
93
}
92
94
93
- struct thread_data {
94
- Semaphore *sem;
95
- uint32_t data;
96
- };
97
-
98
- void single_thread (struct thread_data *data)
95
+ void single_thread (struct test_data *data)
99
96
{
100
97
data->sem ->acquire ();
101
98
data->data ++;
@@ -104,7 +101,7 @@ void single_thread(struct thread_data *data)
104
101
/* * Test single thread
105
102
106
103
Given a two threads A & B and a semaphore (with count of 0) and a counter (equals to 0)
107
- when thread B calls @a wait
104
+ when thread B calls @a acquire
108
105
then thread B waits for a token to become available
109
106
then the counter is equal to 0
110
107
when thread A calls @a release on the semaphore
@@ -115,7 +112,7 @@ void test_single_thread()
115
112
{
116
113
Thread t (osPriorityNormal, THREAD_STACK_SIZE);
117
114
Semaphore sem (0 );
118
- struct thread_data data;
115
+ struct test_data data;
119
116
osStatus res;
120
117
121
118
data.sem = &sem;
@@ -147,8 +144,8 @@ void timeout_thread(Semaphore *sem)
147
144
/* * Test timeout
148
145
149
146
Given thread and a semaphore with no tokens available
150
- when thread calls @a wait on the semaphore with timeout of 10ms
151
- then the thread waits for 10ms and timeouts after
147
+ when a thread calls @a try_acquire_for with a timeout of 30ms
148
+ then the thread is blocked for up to 30ms and timeouts after.
152
149
*/
153
150
void test_timeout ()
154
151
{
@@ -167,17 +164,112 @@ void test_timeout()
167
164
t.join ();
168
165
TEST_ASSERT_UINT32_WITHIN (5000 , 30000 , timer.read_us ());
169
166
}
167
+ #endif
168
+
169
+ void test_ticker_release (struct test_data *data)
170
+ {
171
+ osStatus res;
172
+ data->data ++;
173
+ res = data->sem ->release ();
174
+ TEST_ASSERT_EQUAL (osOK, res);
175
+ }
176
+
177
+ /* * Test semaphore acquire
178
+
179
+ Given a semaphore with no tokens available and ticker with the callback registered
180
+ when the main thread calls @a acquire
181
+ then the main thread is blocked
182
+ when callback calls @a release on the semaphore
183
+ then the main thread is unblocked
184
+ */
185
+ void test_semaphore_acquire ()
186
+ {
187
+ Semaphore sem (0 );
188
+ struct test_data data;
189
+
190
+ data.sem = &sem;
191
+ data.data = 0 ;
192
+ Ticker t1;
193
+ t1.attach_us (callback (test_ticker_release, &data), 3000 );
194
+ sem.acquire ();
195
+ t1.detach ();
196
+
197
+ TEST_ASSERT_EQUAL (1 , data.data );
198
+ }
199
+
200
+ void test_ticker_try_acquire (Semaphore *sem)
201
+ {
202
+ osStatus res;
203
+ res = sem->try_acquire ();
204
+ TEST_ASSERT_FALSE (res);
205
+ }
206
+
207
+ /* * Test semaphore try acquire
208
+
209
+ Given a semaphore with no tokens available and ticker with the callback registered
210
+ when callback tries to acquire the semaphore, it fails.
211
+ */
212
+ void test_semaphore_try_acquire ()
213
+ {
214
+ Semaphore sem (0 );
215
+ Ticker t1;
216
+ t1.attach_us (callback (test_ticker_try_acquire, &sem), 3000 );
217
+ ThisThread::sleep_for (4 );
218
+ t1.detach ();
219
+ }
220
+
221
+
222
+ /* * Test semaphore try timeout
223
+
224
+ Given a semaphore with no tokens available
225
+ when the main thread calls @a try_acquire_for with 3ms timeout
226
+ then the main thread is blocked for 3ms and timeouts after
227
+ */
228
+ void test_semaphore_try_timeout ()
229
+ {
230
+ Semaphore sem (0 );
231
+ bool res;
232
+ res = sem.try_acquire_for (3 );
233
+ TEST_ASSERT_FALSE (res);
234
+ }
235
+
236
+
237
+ void test_ticker_semaphore_release (struct Semaphore *sem)
238
+ {
239
+ osStatus res;
240
+ res = sem->release ();
241
+ TEST_ASSERT_EQUAL (osOK, res);
242
+ }
243
+
244
+ /* * Test semaphore try acquire timeout
245
+
246
+ Given a semaphore with no tokens available and ticker with the callback registered
247
+ when the main thread calls @a try_acquire_for with 10ms timeout
248
+ then the main thread is blocked for up to 10ms
249
+ when callback call @a release on the semaphore after 3ms
250
+ then the main thread is unblocked.
251
+ */
252
+ void test_semaphore_try_acquire_timeout ()
253
+ {
254
+ Semaphore sem (0 );
255
+ bool res;
256
+ Ticker t1;
257
+ t1.attach_us (callback (test_ticker_semaphore_release, &sem), 3000 );
258
+ res = sem.try_acquire_for (10 );
259
+ t1.detach ();
260
+ TEST_ASSERT_TRUE (res);
261
+ }
170
262
171
263
/* * Test no timeouts
172
264
173
265
Test 1 token no timeout
174
266
Given thread and a semaphore with one token available
175
- when thread calls @a wait on the semaphore with timeout of 0ms
267
+ when thread calls @a try_acquire with timeout of 0ms
176
268
then the thread acquires the token immediately
177
269
178
270
Test 0 tokens no timeout
179
271
Given thread and a semaphore with no tokens available
180
- when thread calls @a wait on the semaphore with timeout of 0ms
272
+ when thread calls @a try_acquire with timeout of 0ms
181
273
then the thread returns immediately without acquiring a token
182
274
*/
183
275
template <int T>
@@ -197,7 +289,7 @@ void test_no_timeout()
197
289
/* * Test multiple tokens wait
198
290
199
291
Given a thread and a semaphore initialized with 5 tokens
200
- when thread calls @a wait 6 times on the semaphore
292
+ when thread calls @a try_acquire 6 times in a loop
201
293
then the token counts goes to zero
202
294
*/
203
295
void test_multiple_tokens_wait ()
@@ -235,13 +327,19 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
235
327
}
236
328
237
329
Case cases[] = {
238
- Case (" Test single thread" , test_single_thread),
239
- Case (" Test timeout" , test_timeout),
240
330
Case (" Test 1 token no timeout" , test_no_timeout<1 >),
241
331
Case (" Test 0 tokens no timeout" , test_no_timeout<0 >),
242
332
Case (" Test multiple tokens wait" , test_multiple_tokens_wait),
243
333
Case (" Test multiple tokens release" , test_multiple_tokens_release),
334
+ Case (" Test semaphore acquire" , test_semaphore_acquire),
335
+ Case (" Test semaphore try acquire" , test_semaphore_try_acquire),
336
+ Case (" Test semaphore try timeout" , test_semaphore_try_timeout),
337
+ Case (" Test semaphore try acquire timeout" , test_semaphore_try_acquire_timeout),
338
+ #if defined(MBED_CONF_RTOS_PRESENT)
339
+ Case (" Test single thread" , test_single_thread),
340
+ Case (" Test timeout" , test_timeout),
244
341
Case (" Test multiple threads" , test_multi)
342
+ #endif
245
343
};
246
344
247
345
Specification specification (test_setup, cases);
@@ -252,4 +350,3 @@ int main()
252
350
}
253
351
254
352
#endif // !DEVICE_USTICKER
255
- #endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)
0 commit comments