Maxim nexpaq / nexpaq_dev
Committer:
nexpaq
Date:
Fri Nov 04 20:54:50 2016 +0000
Revision:
1:d96dbedaebdb
Parent:
0:6c56fb4bc5f0
Removed extra directories for other platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 0:6c56fb4bc5f0 1 #include "mbed.h"
nexpaq 0:6c56fb4bc5f0 2 #include "greentea-client/test_env.h"
nexpaq 0:6c56fb4bc5f0 3 #include "unity.h"
nexpaq 0:6c56fb4bc5f0 4 #include "utest.h"
nexpaq 0:6c56fb4bc5f0 5 #include "rtos.h"
nexpaq 0:6c56fb4bc5f0 6 #include "SynchronizedIntegral.h"
nexpaq 0:6c56fb4bc5f0 7 #include "LockGuard.h"
nexpaq 0:6c56fb4bc5f0 8
nexpaq 0:6c56fb4bc5f0 9 #if defined(MBED_RTOS_SINGLE_THREAD)
nexpaq 0:6c56fb4bc5f0 10 #error [NOT_SUPPORTED] test not supported
nexpaq 0:6c56fb4bc5f0 11 #endif
nexpaq 0:6c56fb4bc5f0 12
nexpaq 0:6c56fb4bc5f0 13 /*
nexpaq 0:6c56fb4bc5f0 14 * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
nexpaq 0:6c56fb4bc5f0 15 * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
nexpaq 0:6c56fb4bc5f0 16 * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
nexpaq 0:6c56fb4bc5f0 17 */
nexpaq 0:6c56fb4bc5f0 18 #if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832)
nexpaq 0:6c56fb4bc5f0 19 #define STACK_SIZE 512
nexpaq 0:6c56fb4bc5f0 20 #else
nexpaq 0:6c56fb4bc5f0 21 #define STACK_SIZE DEFAULT_STACK_SIZE
nexpaq 0:6c56fb4bc5f0 22 #endif
nexpaq 0:6c56fb4bc5f0 23
nexpaq 0:6c56fb4bc5f0 24 using namespace utest::v1;
nexpaq 0:6c56fb4bc5f0 25
nexpaq 0:6c56fb4bc5f0 26 // The counter type used accross all the tests
nexpaq 0:6c56fb4bc5f0 27 // It is internall ysynchronized so read
nexpaq 0:6c56fb4bc5f0 28 typedef SynchronizedIntegral<int> counter_t;
nexpaq 0:6c56fb4bc5f0 29
nexpaq 0:6c56fb4bc5f0 30 // Tasks with different functions to test on threads
nexpaq 0:6c56fb4bc5f0 31 void increment(counter_t* counter) {
nexpaq 0:6c56fb4bc5f0 32 (*counter)++;
nexpaq 0:6c56fb4bc5f0 33 }
nexpaq 0:6c56fb4bc5f0 34
nexpaq 0:6c56fb4bc5f0 35 void increment_with_yield(counter_t* counter) {
nexpaq 0:6c56fb4bc5f0 36 Thread::yield();
nexpaq 0:6c56fb4bc5f0 37 (*counter)++;
nexpaq 0:6c56fb4bc5f0 38 }
nexpaq 0:6c56fb4bc5f0 39
nexpaq 0:6c56fb4bc5f0 40 void increment_with_wait(counter_t* counter) {
nexpaq 0:6c56fb4bc5f0 41 Thread::wait(100);
nexpaq 0:6c56fb4bc5f0 42 (*counter)++;
nexpaq 0:6c56fb4bc5f0 43 }
nexpaq 0:6c56fb4bc5f0 44
nexpaq 0:6c56fb4bc5f0 45 void increment_with_child(counter_t* counter) {
nexpaq 0:6c56fb4bc5f0 46 Thread child(counter, increment, osPriorityNormal, STACK_SIZE);
nexpaq 0:6c56fb4bc5f0 47 child.join();
nexpaq 0:6c56fb4bc5f0 48 }
nexpaq 0:6c56fb4bc5f0 49
nexpaq 0:6c56fb4bc5f0 50 void increment_with_murder(counter_t* counter) {
nexpaq 0:6c56fb4bc5f0 51 {
nexpaq 0:6c56fb4bc5f0 52 // take ownership of the counter mutex so it prevent the child to
nexpaq 0:6c56fb4bc5f0 53 // modify counter.
nexpaq 0:6c56fb4bc5f0 54 LockGuard lock(counter->internal_mutex());
nexpaq 0:6c56fb4bc5f0 55 Thread child(counter, increment, osPriorityNormal, STACK_SIZE);
nexpaq 0:6c56fb4bc5f0 56 child.terminate();
nexpaq 0:6c56fb4bc5f0 57 }
nexpaq 0:6c56fb4bc5f0 58
nexpaq 0:6c56fb4bc5f0 59 (*counter)++;
nexpaq 0:6c56fb4bc5f0 60 }
nexpaq 0:6c56fb4bc5f0 61
nexpaq 0:6c56fb4bc5f0 62 void self_terminate(Thread *self) {
nexpaq 0:6c56fb4bc5f0 63 self->terminate();
nexpaq 0:6c56fb4bc5f0 64 // Code should not get here
nexpaq 0:6c56fb4bc5f0 65 TEST_ASSERT(0);
nexpaq 0:6c56fb4bc5f0 66 }
nexpaq 0:6c56fb4bc5f0 67
nexpaq 0:6c56fb4bc5f0 68 // Tests that spawn tasks in different configurations
nexpaq 0:6c56fb4bc5f0 69 template <void (*F)(counter_t *)>
nexpaq 0:6c56fb4bc5f0 70 void test_single_thread() {
nexpaq 0:6c56fb4bc5f0 71 counter_t counter(0);
nexpaq 0:6c56fb4bc5f0 72 Thread thread(&counter, F, osPriorityNormal, STACK_SIZE);
nexpaq 0:6c56fb4bc5f0 73 thread.join();
nexpaq 0:6c56fb4bc5f0 74 TEST_ASSERT_EQUAL(counter, 1);
nexpaq 0:6c56fb4bc5f0 75 }
nexpaq 0:6c56fb4bc5f0 76
nexpaq 0:6c56fb4bc5f0 77 template <int N, void (*F)(counter_t *)>
nexpaq 0:6c56fb4bc5f0 78 void test_parallel_threads() {
nexpaq 0:6c56fb4bc5f0 79 counter_t counter(0);
nexpaq 0:6c56fb4bc5f0 80 Thread *threads[N];
nexpaq 0:6c56fb4bc5f0 81
nexpaq 0:6c56fb4bc5f0 82 for (int i = 0; i < N; i++) {
nexpaq 0:6c56fb4bc5f0 83 threads[i] = new Thread(&counter, F, osPriorityNormal, STACK_SIZE);
nexpaq 0:6c56fb4bc5f0 84 }
nexpaq 0:6c56fb4bc5f0 85
nexpaq 0:6c56fb4bc5f0 86 for (int i = 0; i < N; i++) {
nexpaq 0:6c56fb4bc5f0 87 threads[i]->join();
nexpaq 0:6c56fb4bc5f0 88 delete threads[i];
nexpaq 0:6c56fb4bc5f0 89 }
nexpaq 0:6c56fb4bc5f0 90
nexpaq 0:6c56fb4bc5f0 91 TEST_ASSERT_EQUAL(counter, N);
nexpaq 0:6c56fb4bc5f0 92 }
nexpaq 0:6c56fb4bc5f0 93
nexpaq 0:6c56fb4bc5f0 94 template <int N, void (*F)(counter_t *)>
nexpaq 0:6c56fb4bc5f0 95 void test_serial_threads() {
nexpaq 0:6c56fb4bc5f0 96 counter_t counter(0);
nexpaq 0:6c56fb4bc5f0 97
nexpaq 0:6c56fb4bc5f0 98 for (int i = 0; i < N; i++) {
nexpaq 0:6c56fb4bc5f0 99 Thread thread(&counter, F, osPriorityNormal, STACK_SIZE);
nexpaq 0:6c56fb4bc5f0 100 thread.join();
nexpaq 0:6c56fb4bc5f0 101 }
nexpaq 0:6c56fb4bc5f0 102
nexpaq 0:6c56fb4bc5f0 103 TEST_ASSERT_EQUAL(counter, N);
nexpaq 0:6c56fb4bc5f0 104 }
nexpaq 0:6c56fb4bc5f0 105
nexpaq 0:6c56fb4bc5f0 106 void test_self_terminate() {
nexpaq 0:6c56fb4bc5f0 107 Thread *thread = new Thread(osPriorityNormal, STACK_SIZE);
nexpaq 0:6c56fb4bc5f0 108 thread->start(thread, self_terminate);
nexpaq 0:6c56fb4bc5f0 109 thread->join();
nexpaq 0:6c56fb4bc5f0 110 delete thread;
nexpaq 0:6c56fb4bc5f0 111 }
nexpaq 0:6c56fb4bc5f0 112
nexpaq 0:6c56fb4bc5f0 113 utest::v1::status_t test_setup(const size_t number_of_cases) {
nexpaq 0:6c56fb4bc5f0 114 GREENTEA_SETUP(40, "default_auto");
nexpaq 0:6c56fb4bc5f0 115 return verbose_test_setup_handler(number_of_cases);
nexpaq 0:6c56fb4bc5f0 116 }
nexpaq 0:6c56fb4bc5f0 117
nexpaq 0:6c56fb4bc5f0 118 // Test cases
nexpaq 0:6c56fb4bc5f0 119 Case cases[] = {
nexpaq 0:6c56fb4bc5f0 120 Case("Testing single thread", test_single_thread<increment>),
nexpaq 0:6c56fb4bc5f0 121 Case("Testing parallel threads", test_parallel_threads<3, increment>),
nexpaq 0:6c56fb4bc5f0 122 Case("Testing serial threads", test_serial_threads<10, increment>),
nexpaq 0:6c56fb4bc5f0 123
nexpaq 0:6c56fb4bc5f0 124 Case("Testing single thread with yield", test_single_thread<increment_with_yield>),
nexpaq 0:6c56fb4bc5f0 125 Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>),
nexpaq 0:6c56fb4bc5f0 126 Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>),
nexpaq 0:6c56fb4bc5f0 127
nexpaq 0:6c56fb4bc5f0 128 Case("Testing single thread with wait", test_single_thread<increment_with_wait>),
nexpaq 0:6c56fb4bc5f0 129 Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>),
nexpaq 0:6c56fb4bc5f0 130 Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>),
nexpaq 0:6c56fb4bc5f0 131
nexpaq 0:6c56fb4bc5f0 132 Case("Testing single thread with child", test_single_thread<increment_with_child>),
nexpaq 0:6c56fb4bc5f0 133 Case("Testing parallel threads with child", test_parallel_threads<2, increment_with_child>),
nexpaq 0:6c56fb4bc5f0 134 Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>),
nexpaq 0:6c56fb4bc5f0 135
nexpaq 0:6c56fb4bc5f0 136 Case("Testing single thread with murder", test_single_thread<increment_with_murder>),
nexpaq 0:6c56fb4bc5f0 137 Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>),
nexpaq 0:6c56fb4bc5f0 138 Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>),
nexpaq 0:6c56fb4bc5f0 139
nexpaq 0:6c56fb4bc5f0 140 Case("Testing thread self terminate", test_self_terminate),
nexpaq 0:6c56fb4bc5f0 141 };
nexpaq 0:6c56fb4bc5f0 142
nexpaq 0:6c56fb4bc5f0 143 Specification specification(test_setup, cases);
nexpaq 0:6c56fb4bc5f0 144
nexpaq 0:6c56fb4bc5f0 145 int main() {
nexpaq 0:6c56fb4bc5f0 146 return !Harness::run(specification);
nexpaq 0:6c56fb4bc5f0 147 }