Skip to content

Baremetal: Enable Semaphore greentea test #12816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 117 additions & 20 deletions TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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++;
Expand All @@ -104,7 +101,7 @@ void single_thread(struct thread_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
Expand All @@ -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;
Expand Down Expand Up @@ -147,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()
{
Expand All @@ -167,17 +164,112 @@ 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 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()
{
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 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(4);
t1.detach();
}


/** Test semaphore try timeout

Given a semaphore with no tokens available
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(3);
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 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()
{
Semaphore sem(0);
bool res;
Ticker t1;
t1.attach_us(callback(test_ticker_semaphore_release, &sem), 3000);
res = sem.try_acquire_for(10);
t1.detach();
TEST_ASSERT_TRUE(res);
}

/** Test no timeouts

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<int T>
Expand All @@ -197,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()
Expand Down Expand Up @@ -235,13 +327,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);
Expand All @@ -252,4 +350,3 @@ int main()
}

#endif // !DEVICE_USTICKER
#endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)