Fix and update tests to use Chronos APIs

pull/12425/head
Kevin Bracey 2020-02-13 13:18:49 +02:00
parent b17355f588
commit 5601a207cc
10 changed files with 134 additions and 169 deletions

View File

@ -28,22 +28,24 @@
#else
using utest::v1::Case;
using std::milli;
using std::micro;
using namespace std::chrono;
#if defined(__CORTEX_M23) || defined(__CORTEX_M33)
#define TEST_STACK_SIZE 512
#else
#define TEST_STACK_SIZE 256
#endif
#define ONE_MILLI_SEC 1000
volatile uint32_t elapsed_time_ms = 0;
static duration<uint32_t, milli> elapsed_time_ms;
static const int test_timeout = 40;
void update_tick_thread(Mutex *mutex)
{
while (true) {
ThisThread::sleep_for(1);
ThisThread::sleep_for(1ms);
mutex->lock();
++elapsed_time_ms;
mutex->unlock();
@ -69,7 +71,7 @@ void test(void)
char _value[128] = { };
int expected_key = 1;
Mutex mutex;
uint32_t elapsed_time;
duration<uint32_t, micro> elapsed_time;
Thread tick_thread(osPriorityHigh, TEST_STACK_SIZE);
tick_thread.start(callback(update_tick_thread, &mutex));
@ -86,7 +88,7 @@ void test(void)
elapsed_time = elapsed_time_ms;
mutex.unlock();
// send base_time
greentea_send_kv(_key, elapsed_time * ONE_MILLI_SEC);
greentea_send_kv(_key, elapsed_time.count());
// wait for 2nd signal from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
@ -95,7 +97,7 @@ void test(void)
elapsed_time = elapsed_time_ms;
mutex.unlock();
// send final_time
greentea_send_kv(_key, elapsed_time * ONE_MILLI_SEC);
greentea_send_kv(_key, elapsed_time.count());
//get the results from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));

View File

@ -29,9 +29,10 @@
#include "rtos.h"
using namespace utest::v1;
using namespace std::chrono_literals;
#define TEST_STACK_SIZE 512
#define TEST_DELAY 10
#define TEST_DELAY 10ms
static int change_counter = 0;
static Mutex mutex;

View File

@ -21,6 +21,7 @@
#include "utest/utest.h"
using utest::v1::Case;
using namespace std::chrono;
#if !DEVICE_USTICKER
#error [NOT_SUPPORTED] UsTicker need to be enabled for this test.
@ -44,14 +45,14 @@ using utest::v1::Case;
#define PROHIBITED_FLAG 0x80000000 /* 10000000000000000000000000000000 */
#define NO_FLAGS 0x0
void send_thread(EventFlags *ef, uint32_t flags, uint32_t wait_ms)
void send_thread(EventFlags *ef, uint32_t flags, milliseconds wait)
{
for (uint32_t i = 0; i <= MAX_FLAG_POS; i++) {
const uint32_t flag = flags & (1 << i);
if (flag) {
ef->set(flag);
if (wait_ms != 0) {
ThisThread::sleep_for(wait_ms);
if (wait != 0ms) {
ThisThread::sleep_for(wait);
}
}
}
@ -60,21 +61,19 @@ void send_thread(EventFlags *ef, uint32_t flags, uint32_t wait_ms)
#if defined(MBED_CONF_RTOS_PRESENT)
Semaphore sync_sem(0, 1);
template<uint32_t flags, uint32_t wait_ms>
void send_thread_sync(EventFlags *ef)
void send_thread_sync(EventFlags *ef, uint32_t flags, milliseconds wait)
{
for (uint32_t i = 0; i <= MAX_FLAG_POS; i++) {
const uint32_t flag = flags & (1 << i);
if (flag) {
sync_sem.acquire();
ef->set(flag);
ThisThread::sleep_for(wait_ms);
ThisThread::sleep_for(wait);
}
}
}
template<uint32_t flags>
void wait_thread_all(EventFlags *ef)
void wait_thread_all(EventFlags *ef, uint32_t flags)
{
uint32_t ret, flags_after_clear;
ret = ef->wait_all(flags);
@ -218,9 +217,9 @@ void test_multi_thread_all(void)
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
thread1.start([&] { send_thread(&ef, FLAG01, 1); });
thread2.start([&] { send_thread(&ef, FLAG02, 2); });
thread3.start([&] { send_thread(&ef, FLAG03, 3); });
thread1.start([&] { send_thread(&ef, FLAG01, 1ms); });
thread2.start([&] { send_thread(&ef, FLAG02, 2ms); });
thread3.start([&] { send_thread(&ef, FLAG03, 3ms); });
uint32_t ret = ef.wait_all(FLAG01 | FLAG02 | FLAG03);
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, ret);
@ -239,9 +238,9 @@ void test_multi_thread_any(void)
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
thread1.start([&] { send_thread(&ef, FLAG01, 1); });
thread2.start([&] { send_thread(&ef, FLAG02, 1); });
thread3.start([&] { send_thread(&ef, FLAG03, 1); });
thread1.start([&] { send_thread(&ef, FLAG01, 1ms); });
thread2.start([&] { send_thread(&ef, FLAG02, 1ms); });
thread3.start([&] { send_thread(&ef, FLAG03, 1ms); });
for (int i = 0; i <= MAX_FLAG_POS; i++) {
uint32_t flag = 1 << i;
@ -265,16 +264,16 @@ void test_multi_thread_any_timeout(void)
EventFlags ef;
uint32_t ret;
Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
thread.start(callback(send_thread_sync < FLAG01 | FLAG02 | FLAG03, 1 >, &ef));
thread.start([&] { send_thread_sync(&ef, FLAG01 | FLAG02 | FLAG03, 1ms); });
for (int i = 0; i <= MAX_FLAG_POS; i++) {
uint32_t flag = 1 << i;
ret = ef.wait_any(flag, 10);
ret = ef.wait_any_for(flag, 10ms);
TEST_ASSERT_EQUAL(osFlagsErrorTimeout, ret);
sync_sem.release();
ret = ef.wait_any(flag, 10);
ret = ef.wait_any_for(flag, 10ms);
TEST_ASSERT_EQUAL(flag, ret);
}
ret = ef.get();
@ -294,13 +293,13 @@ void test_multi_thread_any_no_clear(void)
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
thread1.start([&] { send_thread(&ef, FLAG01, 1); });
thread2.start([&] { send_thread(&ef, FLAG02, 1); });
thread3.start([&] { send_thread(&ef, FLAG03, 1); });
thread1.start([&] { send_thread(&ef, FLAG01, 1ms); });
thread2.start([&] { send_thread(&ef, FLAG02, 1ms); });
thread3.start([&] { send_thread(&ef, FLAG03, 1ms); });
for (int i = 0; i <= MAX_FLAG_POS; i++) {
uint32_t flag = 1 << i;
ret = ef.wait_any(flag, osWaitForever, false);
ret = ef.wait_any_for(flag, Kernel::wait_for_u32_forever, false);
TEST_ASSERT(flag | ret);
ret = ef.clear(flag);
TEST_ASSERT(ret < osFlagsError);
@ -322,9 +321,9 @@ void test_multi_thread_all_many_wait(void)
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
thread1.start(callback(wait_thread_all<FLAG01>, &ef));
thread2.start(callback(wait_thread_all<FLAG02>, &ef));
thread3.start(callback(wait_thread_all<FLAG03>, &ef));
thread1.start([&] { wait_thread_all(&ef, FLAG01); });
thread2.start([&] { wait_thread_all(&ef, FLAG02); });
thread3.start([&] { wait_thread_all(&ef, FLAG03); });
ef.set(FLAG01 | FLAG02 | FLAG03);
thread1.join();
@ -337,9 +336,9 @@ void test_multi_thread_all_many_wait(void)
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
thread1.start(callback(wait_thread_all<FLAG01>, &ef));
thread2.start(callback(wait_thread_all<FLAG02>, &ef));
thread3.start(callback(wait_thread_all<FLAG03>, &ef));
thread1.start([&] { wait_thread_all(&ef, FLAG01); });
thread2.start([&] { wait_thread_all(&ef, FLAG02); });
thread3.start([&] { wait_thread_all(&ef, FLAG03); });
ef.set(FLAG01);
thread1.join();
@ -362,10 +361,10 @@ void test_multi_eventflags_all(void)
{
EventFlags ef;
Ticker t1, t2, t3;
t1.attach_us([&] { send_thread(&ef, FLAG01, 0); }, 3000);
t2.attach_us([&] { send_thread(&ef, FLAG02, 0); }, 4000);
t3.attach_us([&] { send_thread(&ef, FLAG03, 0); }, 5000);
uint32_t ret = ef.wait_all(FLAG01 | FLAG02 | FLAG03, 20, false);
t1.attach([&] { send_thread(&ef, FLAG01, 0ms); }, 3ms);
t2.attach([&] { send_thread(&ef, FLAG02, 0ms); }, 4ms);
t3.attach([&] { send_thread(&ef, FLAG03, 0ms); }, 5ms);
uint32_t ret = ef.wait_all_for(FLAG01 | FLAG02 | FLAG03, 20ms, false);
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, ret);
}
@ -380,9 +379,9 @@ void test_multi_eventflags_any(void)
EventFlags ef;
uint32_t ret;
Ticker t1, t2, t3;
t1.attach_us([&] { send_thread(&ef, FLAG01, 0); }, 3000);
t2.attach_us([&] { send_thread(&ef, FLAG02, 0); }, 4000);
t3.attach_us([&] { send_thread(&ef, FLAG03, 0); }, 5000);
t1.attach([&] { send_thread(&ef, FLAG01, 0ms); }, 3ms);
t2.attach([&] { send_thread(&ef, FLAG02, 0ms); }, 4ms);
t3.attach([&] { send_thread(&ef, FLAG03, 0ms); }, 5ms);
for (int i = 0; i <= MAX_FLAG_POS; i++) {
uint32_t flag = 1 << i;
@ -404,9 +403,9 @@ void test_multi_eventflags_any_no_clear(void)
EventFlags ef;
uint32_t ret;
Ticker t1, t2, t3;
t1.attach_us([&] { send_thread(&ef, FLAG01, 0); }, 3000);
t2.attach_us([&] { send_thread(&ef, FLAG02, 0); }, 4000);
t3.attach_us([&] { send_thread(&ef, FLAG03, 0); }, 5000);
t1.attach([&] { send_thread(&ef, FLAG01, 0ms); }, 3ms);
t2.attach([&] { send_thread(&ef, FLAG02, 0ms); }, 4ms);
t3.attach([&] { send_thread(&ef, FLAG03, 0ms); }, 5ms);
for (int i = 0; i <= MAX_FLAG_POS; i++) {
uint32_t flag = 1 << i;

View File

@ -21,18 +21,17 @@
#include "rtos/Kernel.h"
#include "mbed.h"
using namespace std::chrono_literals;
using utest::v1::Case;
#define TEST_REPEAT_COUNT 1000
#define NUM_WAIT_TICKS 1000
#define NUM_WAIT_TICKS rtos::Kernel::Clock::duration(1s)
// all in [us]
#define ONE_SECOND 1000000
#define SMALL_DELTA 1500 // 0.15%
#define BIG_DELTA 15000 // 1.5%
#define ONE_SECOND Timer::duration(1s)
#define SMALL_DELTA Timer::duration(1500us) // 0.15%
#define BIG_DELTA Timer::duration(15000us) // 1.5%
#if defined(MBED_CONF_RTOS_PRESENT)
/** Test if kernel ticker frequency is 1kHz
Given a RTOS kernel ticker
@ -41,25 +40,27 @@ using utest::v1::Case;
*/
void test_frequency()
{
#if defined(MBED_CONF_RTOS_PRESENT)
uint32_t freq = osKernelGetTickFreq();
TEST_ASSERT_EQUAL_UINT32_MESSAGE(1000, freq, "Expected SysTick frequency is 1kHz");
}
#endif
TEST_ASSERT_TRUE_MESSAGE((std::ratio_equal<rtos::Kernel::Clock::period, std::milli>::value), "Expected Kernel::Clock frequency is 1kHz");
}
/** Test if kernel ticker increments by one
Given a RTOS kernel ticker
When perform subsequent calls of @a rtos::Kernel::get_ms_count
When perform subsequent calls of @a rtos::Kernel::Clock::now
Then subsequent reads should not differ by more than one
*/
void test_increment(void)
{
for (uint32_t i = 0; i < TEST_REPEAT_COUNT; i++) {
const uint64_t start = rtos::Kernel::get_ms_count();
auto start = rtos::Kernel::Clock::now();
while (true) {
uint64_t diff = rtos::Kernel::get_ms_count() - start;
if (diff != 0) {
TEST_ASSERT_EQUAL_UINT64(1, diff);
rtos::Kernel::Clock::duration diff = rtos::Kernel::Clock::now() - start;
if (diff.count() != 0) {
TEST_ASSERT_EQUAL_INT64(1, diff.count());
break;
}
}
@ -69,43 +70,41 @@ void test_increment(void)
/** Test if kernel ticker interval is 1ms
Given a RTOS kernel ticker
When perform subsequent calls of @a rtos::Kernel::get_ms_count
When perform subsequent calls of @a rtos::Kernel::Clock::now
Then the ticker interval should be 1ms
*/
void test_interval()
{
uint64_t start, stop;
Kernel::Clock::time_point start, stop;
Timer timer;
start = rtos::Kernel::get_ms_count();
start = rtos::Kernel::Clock::now();
// wait for tick
do {
stop = rtos::Kernel::get_ms_count();
} while ((stop - start) == 0);
stop = rtos::Kernel::Clock::now();
} while (stop == start);
timer.start();
start = stop;
// wait for NUM_WAIT_TICKS ticks
do {
stop = rtos::Kernel::get_ms_count();
stop = rtos::Kernel::Clock::now();
} while ((stop - start) != NUM_WAIT_TICKS);
timer.stop();
TEST_ASSERT_EQUAL_UINT64(NUM_WAIT_TICKS, (stop - start));
TEST_ASSERT_EQUAL_INT64(NUM_WAIT_TICKS.count(), (stop - start).count());
#if defined(NO_SYSTICK) || defined(MBED_TICKLESS)
// On targets with NO_SYSTICK/MBED_TICKLESS enabled, systick is emulated by lp_ticker what makes it less accurate
// for more details https://os.mbed.com/docs/latest/reference/tickless.html
TEST_ASSERT_UINT64_WITHIN(BIG_DELTA, ONE_SECOND, timer.read_high_resolution_us());
TEST_ASSERT_INT64_WITHIN(BIG_DELTA.count(), ONE_SECOND.count(), timer.read_duration().count());
#else
TEST_ASSERT_UINT64_WITHIN(SMALL_DELTA, ONE_SECOND, timer.read_high_resolution_us());
TEST_ASSERT_INT64_WITHIN(SMALL_DELTA.count(), ONE_SECOND.count(), timer.read_duration().count());
#endif
}
// Test cases
Case cases[] = {
#if defined(MBED_CONF_RTOS_PRESENT)
Case("Test kernel ticker frequency", test_frequency),
#endif
Case("Test if kernel ticker increments by one", test_increment),
Case("Test if kernel ticker interval is 1ms", test_interval)
};

View File

@ -29,6 +29,7 @@
#include "rtos.h"
using namespace utest::v1;
using namespace std::chrono;
#if defined(__CORTEX_M23) || defined(__CORTEX_M33)
#define TEST_STACK_SIZE 768
@ -36,8 +37,8 @@ using namespace utest::v1;
#define TEST_STACK_SIZE 512
#endif
#define TEST_LONG_DELAY 20
#define TEST_DELAY 10
#define TEST_LONG_DELAY 20ms
#define TEST_DELAY 10ms
#define SIGNALS_TO_EMIT 100
Mutex stdio_mutex;
@ -89,9 +90,9 @@ void test_thread(int const *thread_delay)
*/
void test_multiple_threads(void)
{
const int t1_delay = TEST_DELAY * 1;
const int t2_delay = TEST_DELAY * 2;
const int t3_delay = TEST_DELAY * 3;
const Kernel::Clock::duration t1_delay = TEST_DELAY * 1;
const Kernel::Clock::duration t2_delay = TEST_DELAY * 2;
const Kernel::Clock::duration t3_delay = TEST_DELAY * 3;
Thread t2(osPriorityNormal, TEST_STACK_SIZE);
Thread t3(osPriorityNormal, TEST_STACK_SIZE);

View File

@ -29,27 +29,32 @@
#include "rtos.h"
using namespace utest::v1;
using namespace std::chrono;
#define TEST_ASSERT_DURATION_WITHIN(delta, expected, actual) \
do { \
using ct = std::common_type_t<decltype(delta), decltype(expected), decltype(actual)>; \
TEST_ASSERT_INT_WITHIN(ct(delta).count(), ct(expected).count(), ct(actual).count()); \
} while (0)
#define THREAD_STACK_SIZE 512
#define TEST_UINT_MSG 0xDEADBEEF
#define TEST_UINT_MSG2 0xE1EE7
#define TEST_TIMEOUT 50
#define TEST_TIMEOUT 50ms
template <uint32_t ms>
void thread_put_uint_msg(Queue<uint32_t, 1> *q)
{
ThisThread::sleep_for(ms);
ThisThread::sleep_for(TEST_TIMEOUT);
osStatus stat = q->put((uint32_t *) TEST_UINT_MSG);
TEST_ASSERT_EQUAL(osOK, stat);
}
template <uint32_t ms, uint32_t val>
void thread_get_uint_msg(Queue<uint32_t, 1> *q)
{
ThisThread::sleep_for(ms);
ThisThread::sleep_for(TEST_TIMEOUT);
osEvent evt = q->get();
TEST_ASSERT_EQUAL(osEventMessage, evt.status);
TEST_ASSERT_EQUAL(val, evt.value.v);
TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
}
/** Test pass uint msg
@ -127,7 +132,7 @@ void test_get_empty_no_timeout()
{
Queue<uint32_t, 1> q;
osEvent evt = q.get(0);
osEvent evt = q.get(0ms);
TEST_ASSERT_EQUAL(osOK, evt.status);
}
@ -143,9 +148,9 @@ void test_get_empty_timeout()
Timer timer;
timer.start();
osEvent evt = q.get(50);
osEvent evt = q.get(50ms);
TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us());
TEST_ASSERT_DURATION_WITHIN(5ms, 50ms, timer.elapsed_time());
}
/** Test get empty wait forever
@ -161,7 +166,7 @@ void test_get_empty_wait_forever()
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
Queue<uint32_t, 1> q;
t.start(callback(thread_put_uint_msg<TEST_TIMEOUT>, &q));
t.start(callback(thread_put_uint_msg, &q));
Timer timer;
timer.start();
@ -169,7 +174,7 @@ void test_get_empty_wait_forever()
osEvent evt = q.get();
TEST_ASSERT_EQUAL(osEventMessage, evt.status);
TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time());
}
/** Test put full no timeout
@ -207,13 +212,13 @@ void test_put_full_timeout()
stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT);
TEST_ASSERT_EQUAL(osErrorTimeout, stat);
TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time());
}
/** Test put full wait forever
*
* Given two threads A & B and a queue with one slot for uint32_t data
* When thread A puts a message to the queue and tries to put second one with @a osWaitForever timeout
* When thread A puts a message to the queue and tries to put second one with @a Kernel::wait_for_u32_forever timeout
* Then thread waits for a slot to become empty in the queue
* When thread B takes one message out of the queue
* Then thread A successfully inserts message into the queue
@ -223,16 +228,16 @@ void test_put_full_waitforever()
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
Queue<uint32_t, 1> q;
t.start(callback(thread_get_uint_msg<TEST_TIMEOUT, TEST_UINT_MSG>, &q));
t.start(callback(thread_get_uint_msg, &q));
osStatus stat = q.put((uint32_t *) TEST_UINT_MSG);
TEST_ASSERT_EQUAL(osOK, stat);
Timer timer;
timer.start();
stat = q.put((uint32_t *) TEST_UINT_MSG, osWaitForever);
stat = q.put((uint32_t *) TEST_UINT_MSG, Kernel::wait_for_u32_forever);
TEST_ASSERT_EQUAL(osOK, stat);
TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time());
t.join();
}

View File

@ -25,17 +25,24 @@
#include "rtos.h"
using namespace utest::v1;
using namespace std::chrono;
struct test_data {
Semaphore *sem;
uint32_t data;
};
#define TEST_ASSERT_DURATION_WITHIN(delta, expected, actual) \
do { \
using ct = std::common_type_t<decltype(delta), decltype(expected), decltype(actual)>; \
TEST_ASSERT_INT_WITHIN(ct(delta).count(), ct(expected).count(), ct(actual).count()); \
} while (0)
#if defined(MBED_CONF_RTOS_PRESENT)
#define THREAD_DELAY 30
#define THREAD_DELAY 30ms
#define SEMAPHORE_SLOTS 2
#define SEM_CHANGES 100
#define SHORT_WAIT 5
#define SHORT_WAIT 5ms
#define THREAD_STACK_SIZE 320 /* larger stack cause out of heap memory on some 16kB RAM boards in multi thread test*/
@ -45,9 +52,9 @@ volatile int change_counter = 0;
volatile int sem_counter = 0;
volatile bool sem_defect = false;
void test_thread(int const *delay)
void test_thread(rtos::Kernel::Clock::duration const *delay)
{
const int thread_delay = *delay;
const auto thread_delay = *delay;
while (true) {
two_slots.acquire();
sem_counter++;
@ -70,9 +77,9 @@ void test_thread(int const *delay)
*/
void test_multi()
{
const int t1_delay = THREAD_DELAY * 1;
const int t2_delay = THREAD_DELAY * 2;
const int t3_delay = THREAD_DELAY * 3;
const rtos::Kernel::Clock::duration t1_delay = THREAD_DELAY * 1;
const rtos::Kernel::Clock::duration t2_delay = THREAD_DELAY * 2;
const rtos::Kernel::Clock::duration t3_delay = THREAD_DELAY * 3;
Thread t1(osPriorityNormal, THREAD_STACK_SIZE);
Thread t2(osPriorityNormal, THREAD_STACK_SIZE);
@ -137,7 +144,7 @@ void test_single_thread()
void timeout_thread(Semaphore *sem)
{
bool acquired = sem->try_acquire_for(30);
bool acquired = sem->try_acquire_for(30ms);
TEST_ASSERT_FALSE(acquired);
}
@ -162,7 +169,7 @@ void test_timeout()
TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
t.join();
TEST_ASSERT_UINT32_WITHIN(5000, 30000, timer.read_us());
TEST_ASSERT_DURATION_WITHIN(5ms, 30ms, timer.elapsed_time());
}
#endif
@ -190,7 +197,7 @@ void test_semaphore_acquire()
data.sem = &sem;
data.data = 0;
Ticker t1;
t1.attach_us(callback(test_ticker_release, &data), 3000);
t1.attach(callback(test_ticker_release, &data), 3ms);
sem.acquire();
t1.detach();
@ -213,8 +220,8 @@ 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.attach(callback(test_ticker_try_acquire, &sem), 3ms);
ThisThread::sleep_for(4ms);
t1.detach();
}
@ -229,7 +236,7 @@ void test_semaphore_try_timeout()
{
Semaphore sem(0);
bool res;
res = sem.try_acquire_for(3);
res = sem.try_acquire_for(3ms);
TEST_ASSERT_FALSE(res);
}
@ -254,8 +261,8 @@ 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.attach(callback(test_ticker_semaphore_release, &sem), 3ms);
res = sem.try_acquire_for(10ms);
t1.detach();
TEST_ASSERT_TRUE(res);
}
@ -283,7 +290,7 @@ void test_no_timeout()
bool acquired = sem.try_acquire();
TEST_ASSERT_EQUAL(T > 0, acquired);
TEST_ASSERT_UINT32_WITHIN(5000, 0, timer.read_us());
TEST_ASSERT_DURATION_WITHIN(5ms, 0ms, timer.elapsed_time());
}
/** Test multiple tokens wait

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD
#define MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD
#include <rtos.h>
/**
* RAII mutex locker.
* The mutex pass in the constructor will be locked for the lifetime of
* the LockGuard instance.
*/
class LockGuard {
public:
/**
* Construct a LockGuard instance and ackire ownership of mutex in input.
* @param mutex The mutex to ackire ownership of.
*/
LockGuard(rtos::Mutex &mutex) : _mutex(mutex)
{
_mutex.lock();
}
/**
* Destruct the lock and release the inner mutex.
*/
~LockGuard()
{
_mutex.unlock();
}
private:
LockGuard(const LockGuard &);
LockGuard &operator=(const LockGuard &);
rtos::Mutex &_mutex;
};
#endif /* MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD */

View File

@ -19,7 +19,9 @@
#define MBEDMICRO_RTOS_MBED_THREADS_SYNCHRONIZED_INTEGRAL
#include <rtos.h>
#include "LockGuard.h"
#include <mstd_mutex>
using mstd::lock_guard;
/**
* Thread safe wrapper for integral types.
@ -33,35 +35,35 @@ public:
// preincrement operator
T operator++()
{
LockGuard lock(_mutex);
lock_guard lock(_mutex);
return ++_value;
}
// predecrement operator
T operator--()
{
LockGuard lock(_mutex);
lock_guard lock(_mutex);
return --_value;
}
// post increment operator
T operator++(int)
{
LockGuard lock(_mutex);
lock_guard lock(_mutex);
return _value++;
}
// post decrement operator
T operator--(int)
{
LockGuard lock(_mutex);
lock_guard lock(_mutex);
return _value--;
}
// conversion operator, used also for <,>,<=,>=,== and !=
operator T() const
{
LockGuard lock(_mutex);
lock_guard lock(_mutex);
return _value;
}

View File

@ -28,7 +28,7 @@
#include "utest.h"
#include "rtos.h"
#include "SynchronizedIntegral.h"
#include "LockGuard.h"
#include <mstd_mutex>
#define THREAD_STACK_SIZE 512
#if defined(__CORTEX_A9) || defined(__CORTEX_M23) || defined(__CORTEX_M33) || defined(TARGET_ARM_FM) || defined(TARGET_CY8CKIT_062_WIFI_BT_PSA)
@ -41,6 +41,7 @@
using namespace utest::v1;
using mstd::lock_guard;
// The counter type used accross all the tests
// It is internall ysynchronized so read
@ -92,7 +93,7 @@ void increment_with_murder(counter_t *counter)
{
// take ownership of the counter mutex so it prevent the child to
// modify counter.
LockGuard lock(counter->internal_mutex());
lock_guard lock(counter->internal_mutex());
Thread *child = new (std::nothrow) Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE);
char *dummy = new (std::nothrow) char[CHILD_THREAD_STACK_SIZE];
delete[] dummy;
@ -293,7 +294,7 @@ void flags_wait()
void flags_wait_tout()
{
uint32_t flags = ThisThread::flags_wait_all_for(0x2, 50);
uint32_t flags = ThisThread::flags_wait_all_for(0x2, 50ms);
TEST_ASSERT_EQUAL(0x1, flags);
}
@ -311,7 +312,7 @@ void flags_wait_multibit_any()
void flags_wait_multibit_tout()
{
uint32_t flags = ThisThread::flags_wait_all_for(0x1 | 0x2, 50);
uint32_t flags = ThisThread::flags_wait_all_for(0x1 | 0x2, 50ms);
TEST_ASSERT_NOT_EQUAL(0x3, flags);
}
@ -375,7 +376,7 @@ void flags_clear()
TEST_ASSERT_EQUAL(0x1, sig);
/* Flags cleared we should get timeout */
uint32_t flags = ThisThread::flags_wait_all_for(0x1, 0);
uint32_t flags = ThisThread::flags_wait_all_for(0x1, 0s);
TEST_ASSERT_EQUAL(0, flags);
}
@ -473,7 +474,7 @@ void test_thread_wait()
Timer timer;
timer.start();
ThisThread::sleep_for(150);
ThisThread::sleep_for(150ms);
TEST_ASSERT_UINT32_WITHIN(50000, 150000, timer.read_us());
}
@ -527,7 +528,7 @@ void test_deleted()
void test_delay_thread()
{
ThisThread::sleep_for(50);
ThisThread::sleep_for(50ms);
}
/** Testing thread states: wait delay