1414 * See the License for the specific language governing permissions and
1515 * limitations under the License.
1616 */
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-
2117#if !DEVICE_USTICKER
2218#error [NOT_SUPPORTED] UsTicker need to be enabled for this test.
2319#else
3026
3127using namespace utest ::v1;
3228
29+ struct test_data {
30+ Semaphore *sem;
31+ uint32_t data;
32+ };
33+
34+ #if defined(MBED_CONF_RTOS_PRESENT)
3335#define THREAD_DELAY 30
3436#define SEMAPHORE_SLOTS 2
3537#define SEM_CHANGES 100
@@ -90,12 +92,7 @@ void test_multi()
9092 }
9193}
9294
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)
9996{
10097 data->sem ->acquire ();
10198 data->data ++;
@@ -104,7 +101,7 @@ void single_thread(struct thread_data *data)
104101/* * Test single thread
105102
106103 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
108105 then thread B waits for a token to become available
109106 then the counter is equal to 0
110107 when thread A calls @a release on the semaphore
@@ -115,7 +112,7 @@ void test_single_thread()
115112{
116113 Thread t (osPriorityNormal, THREAD_STACK_SIZE);
117114 Semaphore sem (0 );
118- struct thread_data data;
115+ struct test_data data;
119116 osStatus res;
120117
121118 data.sem = &sem;
@@ -147,8 +144,8 @@ void timeout_thread(Semaphore *sem)
147144/* * Test timeout
148145
149146 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.
152149 */
153150void test_timeout ()
154151{
@@ -167,17 +164,112 @@ void test_timeout()
167164 t.join ();
168165 TEST_ASSERT_UINT32_WITHIN (5000 , 30000 , timer.read_us ());
169166}
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+ }
170262
171263/* * Test no timeouts
172264
173265Test 1 token no timeout
174266Given 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
176268then the thread acquires the token immediately
177269
178270Test 0 tokens no timeout
179271Given 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
181273then the thread returns immediately without acquiring a token
182274 */
183275template <int T>
@@ -197,7 +289,7 @@ void test_no_timeout()
197289/* * Test multiple tokens wait
198290
199291 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
201293 then the token counts goes to zero
202294 */
203295void test_multiple_tokens_wait ()
@@ -235,13 +327,19 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
235327}
236328
237329Case cases[] = {
238- Case (" Test single thread" , test_single_thread),
239- Case (" Test timeout" , test_timeout),
240330 Case (" Test 1 token no timeout" , test_no_timeout<1 >),
241331 Case (" Test 0 tokens no timeout" , test_no_timeout<0 >),
242332 Case (" Test multiple tokens wait" , test_multiple_tokens_wait),
243333 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),
244341 Case (" Test multiple threads" , test_multi)
342+ #endif
245343};
246344
247345Specification specification (test_setup, cases);
@@ -252,4 +350,3 @@ int main()
252350}
253351
254352#endif // !DEVICE_USTICKER
255- #endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)
0 commit comments