Magnificent7 / Hackathon
Committer:
bryantaylor
Date:
Tue Sep 20 21:26:12 2016 +0000
Revision:
0:eafc3fd41f75
hackathon

Who changed what in which revision?

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