From 8bc7ffe6e3a2b98260ae52fea952beff038df347 Mon Sep 17 00:00:00 2001 From: Rajkumar Kanagaraj Date: Thu, 16 Apr 2020 12:07:05 +0100 Subject: [PATCH 1/2] Baremetal: Enable Semaphore greentea test --- TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp | 121 ++++++++++++++++--- 1 file changed, 107 insertions(+), 14 deletions(-) diff --git a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp index ff06ca179c..e33a98d9a6 100644 --- a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp @@ -14,10 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#if defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT) -#error [NOT_SUPPORTED] Semaphore test cases require RTOS with multithread to run -#else - #if !DEVICE_USTICKER #error [NOT_SUPPORTED] UsTicker need to be enabled for this test. #else @@ -30,6 +26,12 @@ using namespace utest::v1; +struct test_data { + Semaphore *sem; + uint32_t data; +}; + +#if defined(MBED_CONF_RTOS_PRESENT) #define THREAD_DELAY 30 #define SEMAPHORE_SLOTS 2 #define SEM_CHANGES 100 @@ -90,12 +92,7 @@ void test_multi() } } -struct thread_data { - Semaphore *sem; - uint32_t data; -}; - -void single_thread(struct thread_data *data) +void single_thread(struct test_data *data) { data->sem->acquire(); data->data++; @@ -115,7 +112,7 @@ void test_single_thread() { Thread t(osPriorityNormal, THREAD_STACK_SIZE); Semaphore sem(0); - struct thread_data data; + struct test_data data; osStatus res; data.sem = &sem; @@ -167,6 +164,97 @@ void test_timeout() t.join(); TEST_ASSERT_UINT32_WITHIN(5000, 30000, timer.read_us()); } +#endif + +void test_ticker_release(struct test_data *data) +{ + osStatus res; + data->data++; + res = data->sem->release(); + TEST_ASSERT_EQUAL(osOK, res); +} + +/** Test semaphore acquire + + Given a semaphore with no tokens available and ticker with the callback registered + when callbacks update the test data and release semaphore + which will unblock the main thread which is blocked on semaphore acquire. + */ +void test_semaphore_acquire() +{ + Semaphore sem(0); + struct test_data data; + + data.sem = &sem; + data.data = 0; + Ticker t1; + t1.attach_us(callback(test_ticker_release, &data), 3000); + sem.acquire(); + t1.detach(); + + TEST_ASSERT_EQUAL(1, data.data); +} + +void test_ticker_try_acquire(Semaphore *sem) +{ + osStatus res; + res = sem->try_acquire(); + TEST_ASSERT_FALSE(res); +} + +/** Test semaphore try acquire + + Given a semaphore with no tokens available and ticker with the callback registered + when callbacks try to acquire the semaphore will fail. + */ +void test_semaphore_try_acquire() +{ + Semaphore sem(0); + Ticker t1; + t1.attach_us(callback(test_ticker_try_acquire, &sem), 3000); + ThisThread::sleep_for(3); + t1.detach(); +} + + +/** Test semaphore try timeout + + Given a semaphore with no tokens available + when the main thread calls @a wait on the semaphore with try timeout of 5ms + then the main thread waits for 5ms and timeouts after + */ +void test_semaphore_try_timeout() +{ + Semaphore sem(0); + bool res; + res = sem.try_acquire_for(5); + TEST_ASSERT_FALSE(res); +} + + +void test_ticker_semaphore_release(struct Semaphore *sem) +{ + osStatus res; + res = sem->release(); + TEST_ASSERT_EQUAL(osOK, res); +} + +/** Test semaphore try acquire timeout + + Given a semaphore with no tokens available and ticker with the callback registered + when callbacks release the semaphore will unblock the main thread + which is waiting for semaphore with a timeout. + */ +void test_semaphore_try_acquire_timeout() +{ + Semaphore sem(0); + bool res; + Ticker t1; + t1.attach_us(callback(test_ticker_semaphore_release, &sem), 3000); + res = sem.try_acquire_for(30); + t1.detach(); + TEST_ASSERT_TRUE(res); +} /** Test no timeouts @@ -235,13 +323,19 @@ utest::v1::status_t test_setup(const size_t number_of_cases) } Case cases[] = { - Case("Test single thread", test_single_thread), - Case("Test timeout", test_timeout), Case("Test 1 token no timeout", test_no_timeout<1>), Case("Test 0 tokens no timeout", test_no_timeout<0>), Case("Test multiple tokens wait", test_multiple_tokens_wait), Case("Test multiple tokens release", test_multiple_tokens_release), + Case("Test semaphore acquire", test_semaphore_acquire), + Case("Test semaphore try acquire", test_semaphore_try_acquire), + Case("Test semaphore try timeout", test_semaphore_try_timeout), + Case("Test semaphore try acquire timeout", test_semaphore_try_acquire_timeout), +#if defined(MBED_CONF_RTOS_PRESENT) + Case("Test single thread", test_single_thread), + Case("Test timeout", test_timeout), Case("Test multiple threads", test_multi) +#endif }; Specification specification(test_setup, cases); @@ -252,4 +346,3 @@ int main() } #endif // !DEVICE_USTICKER -#endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT) From a24419bde62d71400f7fb0440149db5ba0526809 Mon Sep 17 00:00:00 2001 From: Rajkumar Kanagaraj Date: Fri, 17 Apr 2020 13:01:25 +0100 Subject: [PATCH 2/2] Incorporated the review comments --- TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp | 36 +++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp index e33a98d9a6..0f781e3f34 100644 --- a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp @@ -101,7 +101,7 @@ void single_thread(struct test_data *data) /** Test single thread Given a two threads A & B and a semaphore (with count of 0) and a counter (equals to 0) - when thread B calls @a wait + when thread B calls @a acquire then thread B waits for a token to become available then the counter is equal to 0 when thread A calls @a release on the semaphore @@ -144,8 +144,8 @@ void timeout_thread(Semaphore *sem) /** Test timeout Given thread and a semaphore with no tokens available - when thread calls @a wait on the semaphore with timeout of 10ms - then the thread waits for 10ms and timeouts after + when a thread calls @a try_acquire_for with a timeout of 30ms + then the thread is blocked for up to 30ms and timeouts after. */ void test_timeout() { @@ -177,8 +177,10 @@ void test_ticker_release(struct test_data *data) /** Test semaphore acquire Given a semaphore with no tokens available and ticker with the callback registered - when callbacks update the test data and release semaphore - which will unblock the main thread which is blocked on semaphore acquire. + when the main thread calls @a acquire + then the main thread is blocked + when callback calls @a release on the semaphore + then the main thread is unblocked */ void test_semaphore_acquire() { @@ -205,14 +207,14 @@ void test_ticker_try_acquire(Semaphore *sem) /** Test semaphore try acquire Given a semaphore with no tokens available and ticker with the callback registered - when callbacks try to acquire the semaphore will fail. + when callback tries to acquire the semaphore, it fails. */ void test_semaphore_try_acquire() { Semaphore sem(0); Ticker t1; t1.attach_us(callback(test_ticker_try_acquire, &sem), 3000); - ThisThread::sleep_for(3); + ThisThread::sleep_for(4); t1.detach(); } @@ -220,14 +222,14 @@ void test_semaphore_try_acquire() /** Test semaphore try timeout Given a semaphore with no tokens available - when the main thread calls @a wait on the semaphore with try timeout of 5ms - then the main thread waits for 5ms and timeouts after + when the main thread calls @a try_acquire_for with 3ms timeout + then the main thread is blocked for 3ms and timeouts after */ void test_semaphore_try_timeout() { Semaphore sem(0); bool res; - res = sem.try_acquire_for(5); + res = sem.try_acquire_for(3); TEST_ASSERT_FALSE(res); } @@ -242,8 +244,10 @@ void test_ticker_semaphore_release(struct Semaphore *sem) /** Test semaphore try acquire timeout Given a semaphore with no tokens available and ticker with the callback registered - when callbacks release the semaphore will unblock the main thread - which is waiting for semaphore with a timeout. + when the main thread calls @a try_acquire_for with 10ms timeout + then the main thread is blocked for up to 10ms + when callback call @a release on the semaphore after 3ms + then the main thread is unblocked. */ void test_semaphore_try_acquire_timeout() { @@ -251,7 +255,7 @@ void test_semaphore_try_acquire_timeout() bool res; Ticker t1; t1.attach_us(callback(test_ticker_semaphore_release, &sem), 3000); - res = sem.try_acquire_for(30); + res = sem.try_acquire_for(10); t1.detach(); TEST_ASSERT_TRUE(res); } @@ -260,12 +264,12 @@ void test_semaphore_try_acquire_timeout() Test 1 token no timeout Given thread and a semaphore with one token available -when thread calls @a wait on the semaphore with timeout of 0ms +when thread calls @a try_acquire with timeout of 0ms then the thread acquires the token immediately Test 0 tokens no timeout Given thread and a semaphore with no tokens available -when thread calls @a wait on the semaphore with timeout of 0ms +when thread calls @a try_acquire with timeout of 0ms then the thread returns immediately without acquiring a token */ template @@ -285,7 +289,7 @@ void test_no_timeout() /** Test multiple tokens wait Given a thread and a semaphore initialized with 5 tokens - when thread calls @a wait 6 times on the semaphore + when thread calls @a try_acquire 6 times in a loop then the token counts goes to zero */ void test_multiple_tokens_wait()