ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "greentea-client/test_env.h"
00003 #include "unity.h"
00004 #include "utest.h"
00005 #include "rtos.h"
00006 #include "SynchronizedIntegral.h"
00007 #include "LockGuard.h"
00008 
00009 #if defined(MBED_RTOS_SINGLE_THREAD)
00010   #error [NOT_SUPPORTED] test not supported
00011 #endif
00012 
00013 /*
00014  * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
00015  * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
00016  * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
00017  */
00018 #define PARALLEL_STACK_SIZE 512
00019 
00020 using namespace utest::v1;
00021 
00022 // The counter type used accross all the tests
00023 // It is internall ysynchronized so read
00024 typedef SynchronizedIntegral<int> counter_t;
00025 
00026 // Tasks with different functions to test on threads
00027 void increment(counter_t* counter) {
00028     (*counter)++;
00029 }
00030 
00031 void increment_with_yield(counter_t* counter) {
00032     Thread::yield();
00033     (*counter)++;
00034 }
00035 
00036 void increment_with_wait(counter_t* counter) {
00037     Thread::wait(100);
00038     (*counter)++;
00039 }
00040 
00041 void increment_with_child(counter_t* counter) {
00042     Thread child;
00043     child.start(callback(increment, counter));
00044     child.join();
00045 }
00046 
00047 void increment_with_murder(counter_t* counter) {
00048     {
00049         // take ownership of the counter mutex so it prevent the child to
00050         // modify counter.
00051         LockGuard lock(counter->internal_mutex());
00052         Thread child;
00053         child.start(callback(increment, counter));
00054         child.terminate();
00055     }
00056 
00057     (*counter)++;
00058 }
00059 
00060 void self_terminate(Thread *self) {
00061     self->terminate();
00062     // Code should not get here
00063     TEST_ASSERT(0);
00064 }
00065 
00066 // Tests that spawn tasks in different configurations
00067 template <void (*F)(counter_t *)>
00068 void test_single_thread() {
00069     counter_t counter(0);
00070     Thread thread;
00071     thread.start(callback(F, &counter));
00072     thread.join();
00073     TEST_ASSERT_EQUAL(counter, 1);
00074 }
00075 
00076 template <int N, void (*F)(counter_t *)>
00077 void test_parallel_threads() {
00078     counter_t counter(0);
00079     Thread *threads[N];
00080 
00081     for (int i = 0; i < N; i++) {
00082         threads[i] = new Thread(osPriorityNormal, PARALLEL_STACK_SIZE);
00083         threads[i]->start(callback(F, &counter));
00084     }
00085 
00086     for (int i = 0; i < N; i++) {
00087         threads[i]->join();
00088         delete threads[i];
00089     }
00090 
00091     TEST_ASSERT_EQUAL(counter, N);
00092 }
00093 
00094 template <int N, void (*F)(counter_t *)>
00095 void test_serial_threads() {
00096     counter_t counter(0);
00097 
00098     for (int i = 0; i < N; i++) {
00099         Thread thread;
00100         thread.start(callback(F, &counter));
00101         thread.join();
00102     }
00103 
00104     TEST_ASSERT_EQUAL(counter, N);
00105 }
00106 
00107 void test_self_terminate() {
00108     Thread *thread = new Thread();
00109     thread->start(callback(self_terminate, thread));
00110     thread->join();
00111     delete thread;
00112 }
00113 
00114 utest::v1::status_t  test_setup(const size_t number_of_cases) {
00115     GREENTEA_SETUP(40, "default_auto");
00116     return verbose_test_setup_handler(number_of_cases);
00117 }
00118 
00119 // Test cases
00120 Case cases[] = {
00121     Case("Testing single thread", test_single_thread<increment>),
00122     Case("Testing parallel threads", test_parallel_threads<3, increment>),
00123     Case("Testing serial threads", test_serial_threads<10, increment>),
00124 
00125     Case("Testing single thread with yield", test_single_thread<increment_with_yield>),
00126     Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>),
00127     Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>),
00128 
00129     Case("Testing single thread with wait", test_single_thread<increment_with_wait>),
00130     Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>),
00131     Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>),
00132 
00133     Case("Testing single thread with child", test_single_thread<increment_with_child>),
00134     Case("Testing parallel threads with child", test_parallel_threads<2, increment_with_child>),
00135     Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>),
00136 
00137     Case("Testing single thread with murder", test_single_thread<increment_with_murder>),
00138     Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>),
00139     Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>),
00140 
00141     Case("Testing thread self terminate", test_self_terminate),
00142 };
00143 
00144 Specification specification(test_setup, cases);
00145 
00146 int main() {
00147     return !Harness::run(specification);
00148 }