EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed.h"
00017 #include "greentea-client/test_env.h"
00018 #include "unity.h"
00019 #include "utest.h"
00020 #include "rtos.h"
00021 #include "SynchronizedIntegral.h"
00022 #include "LockGuard.h"
00023 
00024 #if defined(MBED_RTOS_SINGLE_THREAD)
00025   #error [NOT_SUPPORTED] test not supported
00026 #endif
00027 
00028 #define THREAD_STACK_SIZE 512
00029 #define PARALLEL_THREAD_STACK_SIZE 384
00030 #define CHILD_THREAD_STACK_SIZE 384
00031 
00032 using namespace utest::v1;
00033 
00034 // The counter type used accross all the tests
00035 // It is internall ysynchronized so read
00036 typedef SynchronizedIntegral<int> counter_t;
00037 
00038 template<osPriority P, uint32_t S>
00039 class ParallelThread : public Thread {
00040 public:
00041     ParallelThread() : Thread(P, S) { }
00042 };
00043 
00044 // Tasks with different functions to test on threads
00045 void increment(counter_t* counter) {
00046     (*counter)++;
00047 }
00048 
00049 void increment_with_yield(counter_t* counter) {
00050     Thread::yield();
00051     (*counter)++;
00052 }
00053 
00054 void increment_with_wait(counter_t* counter) {
00055     Thread::wait(100);
00056     (*counter)++;
00057 }
00058 
00059 void increment_with_child(counter_t* counter) {
00060     Thread *child = new Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE);
00061     child->start(callback(increment, counter));
00062     child->join();
00063     delete child;
00064 }
00065 
00066 void increment_with_murder(counter_t* counter) {
00067     {
00068         // take ownership of the counter mutex so it prevent the child to
00069         // modify counter.
00070         LockGuard lock(counter->internal_mutex());
00071         Thread *child = new Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE);
00072         child->start(callback(increment, counter));
00073         child->terminate();
00074         delete child;
00075     }
00076 
00077     (*counter)++;
00078 }
00079 
00080 void self_terminate(Thread *self) {
00081     self->terminate();
00082     // Code should not get here
00083     TEST_ASSERT(0);
00084 }
00085 
00086 // Tests that spawn tasks in different configurations
00087 
00088 /** Template for tests: single thread, with yield, with wait, with child, with murder
00089 
00090     Testing single thread
00091     Given single thread is started
00092     when the thread increments the counter
00093     then the final value of the counter is equal to 1
00094 
00095     Testing single thread with yield
00096     Given single thread is started
00097     when the thread yields and then increments the counter
00098     then the final value of the counter is equal to 1
00099 
00100     Testing single thread with wait
00101     Given single thread is started
00102     when the thread waits for 100ms and then increments the counter
00103     then the final value of the counter is equal to 1
00104 
00105     Testing single thread with child
00106     Given single thread is started
00107     when the thread spawns another thread that increments the counter
00108     then the final value of the counter is equal to 1
00109 
00110     Testing serial threads with murder
00111     Given single thread is started
00112     when the parent thread is holding a lock
00113         and the parent thread spawns a child thread that waits for the lock before incrementing the counter
00114         and the parent terminates the child before releasing the lock
00115         and the parent increments the counter
00116     then the final value of the counter is equal to 1
00117 */
00118 template <void (*F)(counter_t *)>
00119 void test_single_thread() {
00120     counter_t counter(0);
00121     Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
00122     thread.start(callback(F, &counter));
00123     thread.join();
00124     TEST_ASSERT_EQUAL(counter, 1);
00125 }
00126 
00127 /** Template for tests: parallel threads, with yield, with wait, with child, with murder
00128 
00129     Testing parallel threads
00130     Given multiple threads are started in parallel
00131     when each of the threads increments the counter
00132     then the final value of the counter is equal to number of threads
00133 
00134     Testing parallel threads with yield
00135     Given multiple threads are started in parallel
00136     when each of the threads yields and then increments the counter
00137     then the final value of the counter is equal to number of threads
00138 
00139     Testing parallel threads with wait
00140     Given multiple threads are started in parallel
00141     when each of the threads waits for 100ms and then increments the counter
00142     then the final value of the counter is equal to number of threads
00143 
00144     Testing parallel threads with child
00145     Given multiple threads are started in parallel
00146     when each of the threads spawns another thread that increments the counter
00147     then the final value of the counter is equal to number of parallel threads
00148 
00149     Testing parallel threads with murder
00150     Given multiple threads are started in parallel
00151     when the parent thread is holding a lock
00152         and the parent thread spawns a child thread that waits for the lock before incrementing the counter
00153         and the parent terminates the child before releasing the lock
00154         and the parent increments the counter
00155     then the final value of the counter is equal to number of parallel threads
00156 */
00157 template <int N, void (*F)(counter_t *)>
00158 void test_parallel_threads() {
00159     counter_t counter(0);
00160     ParallelThread<osPriorityNormal, PARALLEL_THREAD_STACK_SIZE> threads[N];
00161 
00162     for (int i = 0; i < N; i++) {
00163         threads[i].start(callback(F, &counter));
00164     }
00165 
00166     for (int i = 0; i < N; i++) {
00167         threads[i].join();
00168     }
00169 
00170     TEST_ASSERT_EQUAL(counter, N);
00171 }
00172 
00173 /** Template for tests: serial threads, with yield, with wait, with child, with murder
00174 
00175     Testing serial threads
00176     Given multiple threads are started serially
00177     when each of the threads increments the counter
00178     then the final value of the counter is equal to number of threads
00179 
00180     Testing serial threads with yield
00181     Given multiple threads are started serially
00182     when each of the threads yields and then increments the counter
00183     then the final value of the counter is equal to number of threads
00184 
00185     Testing serial threads with wait
00186     Given multiple threads are started serially
00187     when each of the threads waits for 100ms and then increments the counter
00188     then the final value of the counter is equal to number of threads
00189 
00190     Testing serial threads with child
00191     Given multiple threads are started serially
00192     when each of the threads spawns another thread that increments the counter
00193     then the final value of the counter is equal to number of serial threads
00194 
00195     Testing serial threads with murder
00196     Given multiple threads are started serially
00197     when the parent thread is holding a lock
00198         and the parent thread spawns a child thread that waits for the lock before incrementing the counter
00199         and the parent terminates the child before releasing the lock
00200         and the parent increments the counter
00201     then the final value of the counter is equal to number of serial threads
00202 */
00203 template <int N, void (*F)(counter_t *)>
00204 void test_serial_threads() {
00205     counter_t counter(0);
00206 
00207     for (int i = 0; i < N; i++) {
00208         Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
00209         thread.start(callback(F, &counter));
00210         thread.join();
00211     }
00212 
00213     TEST_ASSERT_EQUAL(counter, N);
00214 }
00215 
00216 /** Testing thread self terminate
00217 
00218     Given the thread is running
00219     when the thread calls @a terminate on its self
00220     then the thread terminates execution cleanly
00221  */
00222 void test_self_terminate() {
00223     Thread *thread = new Thread(osPriorityNormal, THREAD_STACK_SIZE);
00224     thread->start(callback(self_terminate, thread));
00225     thread->join();
00226     delete thread;
00227 }
00228 
00229 void signal_wait()
00230 {
00231     osEvent evt = Thread::signal_wait(0x1);
00232     TEST_ASSERT_EQUAL(osEventSignal, evt.status);
00233     TEST_ASSERT_EQUAL(0x1, evt.value.signals);
00234 }
00235 
00236 void signal_wait_tout()
00237 {
00238     osEvent evt = Thread::signal_wait(0x2, 50);
00239     TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
00240 }
00241 
00242 void signal_wait_multibit()
00243 {
00244     osEvent evt = Thread::signal_wait(0x1 | 0x2, 50);
00245     TEST_ASSERT_EQUAL(osEventSignal, evt.status);
00246     TEST_ASSERT_EQUAL(0x3, evt.value.signals);
00247 }
00248 
00249 void signal_wait_multibit_tout()
00250 {
00251     osEvent evt = Thread::signal_wait(0x1 | 0x2, 50);
00252     TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
00253 }
00254 
00255 /**
00256     Testing thread signal: wait
00257     Given two threads (A & B) are started
00258     when thread A executes @a signal_wait(0x1)
00259         and thread B execute @a signal_set(0x1)
00260     then thread A exits the wait and continues execution
00261 
00262     Testing thread signal: timeout
00263     Given two threads (A & B) are started
00264     when thread A executes @a signal_wait(0x1 | 0x2, 50) with a timeout of 50ms
00265         and thread B execute @a signal_set(0x2)
00266     then thread A keeps waiting for correct signal until it timeouts
00267 
00268     Testing thread signal: multi-bit
00269     Given two threads (A & B) are started
00270     when thread A executes @a signal_wait(0x1 | 0x2)
00271         and thread B execute @a signal_set(0x1 | 0x2)
00272     then thread A exits the wait and continues execution
00273 
00274     Testing thread signal: multi-bit timeout
00275     Given two threads (A & B) are started
00276     when thread A executes @a signal_wait(0x1, 50) with a timeout of 50ms
00277         and thread B execute @a signal_set(0x2)
00278     then thread A keeps waiting for correct signal until it timeouts
00279 */
00280 template <int S, void (*F)()>
00281 void test_thread_signal()
00282 {
00283     Thread t_wait(osPriorityNormal, THREAD_STACK_SIZE);
00284 
00285     t_wait.start(callback(F));
00286 
00287     Thread::yield();
00288 
00289     Thread::State state = t_wait.get_state();
00290     TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, state);
00291 
00292     int32_t res = t_wait.signal_set(S);
00293 
00294     t_wait.join();
00295 }
00296 
00297 void signal_clr()
00298 {
00299     Thread::yield();
00300 
00301     int32_t sig = Thread::signal_clr(0x1);
00302     TEST_ASSERT_EQUAL(0x1, sig);
00303 
00304     /* Signal cleared we should get timeout */
00305     osEvent evt = Thread::signal_wait(0x1, 0);
00306     TEST_ASSERT_EQUAL(osOK, evt.status);
00307 }
00308 
00309 /** Testing thread signals: signal clear
00310 
00311     Given two threads (A & B) are started
00312     when thread A executes @a signal_set(0x1)
00313         and thread B execute @a signal_clr(0x1)
00314         and thread B execute @a signal_wait(0x1, 0)
00315     then thread B @a signal_wait status should be osOK indicating a timeout
00316  */
00317 void test_thread_signal_clr()
00318 {
00319     Thread t_wait(osPriorityNormal, THREAD_STACK_SIZE);
00320 
00321     t_wait.start(callback(signal_clr));
00322 
00323     int32_t res = t_wait.signal_set(0x1);
00324     TEST_ASSERT_EQUAL(0x1, res);
00325 
00326     t_wait.join();
00327 }
00328 
00329 void thread_wait_signal() {
00330     Thread::signal_wait(0x1);
00331 }
00332 
00333 void stack_info() {
00334     Thread::signal_wait(0x1);
00335 
00336     thread_wait_signal();
00337 
00338     Thread::signal_wait(0x1);
00339 }
00340 
00341 /** Testing thread stack info
00342 
00343     Given the thread is running
00344     when a function is called from the thread context
00345     then the stack usage goes up
00346         and the reported stack size is as requested in the constructor
00347         and the sum of free and used stack sizes is equal to the total stack size
00348     when the function returns
00349     then the stack usage goes down
00350         and the reported stack size is as requested in the constructor
00351         and the sum of free and used stack sizes is equal to the total stack size
00352  */
00353 void test_thread_stack_info() {
00354     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00355     t.start(callback(stack_info));
00356 
00357     Thread::yield();
00358 
00359     TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.stack_size());
00360     TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.free_stack() + t.used_stack());
00361     uint32_t last_stack = t.used_stack();
00362 
00363     t.signal_set(0x1);
00364     Thread::yield();
00365 
00366     TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.free_stack() + t.used_stack());
00367     TEST_ASSERT(last_stack <= t.used_stack());
00368     last_stack = t.used_stack();
00369 
00370     t.signal_set(0x1);
00371     Thread::yield();
00372 
00373     TEST_ASSERT_EQUAL(THREAD_STACK_SIZE, t.free_stack() + t.used_stack());
00374     TEST_ASSERT(last_stack >= t.used_stack());
00375 
00376     t.signal_set(0x1);
00377 
00378     t.join();
00379 }
00380 
00381 /** Testing thread wait aka delay
00382 
00383     Given the thread is running
00384     when the @a wait function is called
00385     then the thread sleeps for given amount of time
00386  */
00387 void test_thread_wait() {
00388     Timer timer;
00389     timer.start();
00390 
00391     Thread::wait(150);
00392 
00393     TEST_ASSERT_UINT32_WITHIN(50000, 150000, timer.read_us());
00394 }
00395 
00396 /** Testing thread name
00397 
00398     Given a thread is started with a specified name
00399     when the name is queried using @a get_name
00400     then the returned name is as set
00401 */
00402 void test_thread_name() {
00403     const char tname[] = "Amazing thread";
00404     Thread t(osPriorityNormal, THREAD_STACK_SIZE, NULL, tname);
00405     t.start(callback(thread_wait_signal));
00406     TEST_ASSERT_EQUAL(strcmp(tname, t.get_name()), 0);
00407     t.signal_set(0x1);
00408     t.join();
00409 }
00410 
00411 void test_deleted_thread()
00412 {
00413 }
00414 
00415 /** Testing thread states: deleted
00416 
00417     Given the thread is not started
00418     then its state, as reported by @a get_state, is @a Deleted
00419     when the thread is started and finishes executing
00420     then its state, as reported by @a get_state, is @a Deleted
00421  */
00422 void test_deleted()
00423 {
00424     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00425 
00426     TEST_ASSERT_EQUAL(Thread::Deleted, t.get_state());
00427 
00428     t.start(callback(test_deleted_thread));
00429 
00430     t.join();
00431     TEST_ASSERT_EQUAL(Thread::Deleted, t.get_state());
00432 }
00433 
00434 void test_delay_thread()
00435 {
00436     Thread::wait(50);
00437 }
00438 
00439 /** Testing thread states: wait delay
00440 
00441     Given the thread is running
00442     when thread calls @a wait
00443     then its state, as reported by @a get_state, is @a WaitingDelay
00444  */
00445 void test_delay()
00446 {
00447     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00448 
00449     t.start(callback(test_delay_thread));
00450 
00451     Thread::yield();
00452 
00453     TEST_ASSERT_EQUAL(Thread::WaitingDelay, t.get_state());
00454 
00455     t.join();
00456     TEST_ASSERT_EQUAL(Thread::Deleted, t.get_state());
00457 }
00458 
00459 void test_signal_thread()
00460 {
00461     Thread::signal_wait(0x1);
00462 }
00463 
00464 /** Testing thread states: wait signal
00465 
00466     Given the thread is running
00467     when thread waits for a signal
00468     then its state, as reported by @a get_state, is @a WaitingSignal
00469  */
00470 void test_signal()
00471 {
00472     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00473 
00474     t.start(callback(test_signal_thread));
00475 
00476     Thread::yield();
00477 
00478     TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state());
00479 
00480     t.signal_set(0x1);
00481 }
00482 
00483 void test_evt_flag_thread(osEventFlagsId_t evtflg)
00484 {
00485     osEventFlagsWait(evtflg, 0x1, osFlagsWaitAny, osWaitForever);
00486 }
00487 
00488 /** Testing thread states: wait evt flag
00489 
00490     Given the thread is running
00491     when thread waits for an event flag
00492     then its state, as reported by @a get_state, is @a WaitingEventFlag
00493  */
00494 void test_evt_flag()
00495 {
00496     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00497     mbed_rtos_storage_event_flags_t evtflg_mem;
00498     osEventFlagsAttr_t evtflg_attr;
00499     osEventFlagsId_t evtflg;
00500 
00501     evtflg_attr.cb_mem = &evtflg_mem;
00502     evtflg_attr.cb_size = sizeof(evtflg_mem);
00503     evtflg = osEventFlagsNew(&evtflg_attr);
00504     TEST_ASSERT_NOT_EQUAL(NULL, evtflg);
00505 
00506     t.start(callback(test_evt_flag_thread, evtflg));
00507 
00508     Thread::yield();
00509 
00510     TEST_ASSERT_EQUAL(Thread::WaitingEventFlag, t.get_state());
00511 
00512     osEventFlagsSet(evtflg, 0x1);
00513 }
00514 
00515 void test_mutex_thread(Mutex *mutex)
00516 {
00517     mutex->lock();
00518 }
00519 
00520 /** Testing thread states: wait mutex
00521 
00522     Given the thread is running
00523     when thread waits for a mutex
00524     then its state, as reported by @a get_state, is @a WaitingMutex
00525  */
00526 void test_mutex()
00527 {
00528     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00529     Mutex mutex;
00530 
00531     mutex.lock();
00532 
00533     t.start(callback(test_mutex_thread, &mutex));
00534 
00535     Thread::yield();
00536 
00537     TEST_ASSERT_EQUAL(Thread::WaitingMutex, t.get_state());
00538 
00539     mutex.unlock();
00540 }
00541 
00542 void test_semaphore_thread(Semaphore *sem)
00543 {
00544     sem->wait();
00545 }
00546 
00547 /** Testing thread states: wait semaphore
00548 
00549     Given the thread is running
00550     when thread waits for a semaphore
00551     then its state, as reported by @a get_state, is @a WaitingSemaphore
00552  */
00553 void test_semaphore()
00554 {
00555     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00556     Semaphore sem;
00557 
00558     t.start(callback(test_semaphore_thread, &sem));
00559 
00560     Thread::yield();
00561 
00562     TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
00563 
00564     sem.release();
00565 }
00566 
00567 void test_msg_get_thread(Queue<int32_t, 1> *queue)
00568 {
00569     queue->get();
00570 }
00571 
00572 /** Testing thread states: wait message get
00573 
00574     Given the thread is running
00575     when thread tries to get a message from an empty queue
00576     then its state, as reported by @a get_state, is @a WaitingMessageGet
00577  */
00578 void test_msg_get()
00579 {
00580     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00581     Queue<int32_t, 1> queue;
00582 
00583     t.start(callback(test_msg_get_thread, &queue));
00584 
00585     Thread::yield();
00586 
00587     TEST_ASSERT_EQUAL(Thread::WaitingMessageGet, t.get_state());
00588 
00589     queue.put((int32_t *)0xE1EE7);
00590 }
00591 
00592 void test_msg_put_thread(Queue<int32_t, 1> *queue)
00593 {
00594     queue->put((int32_t *)0xDEADBEEF, osWaitForever);
00595 
00596 }
00597 
00598 /** Testing thread states: wait message put
00599 
00600     Given the thread is running
00601     when thread tries to put a message into a full queue
00602     then its state, as reported by @a get_state, is @a WaitingMessagePut
00603  */
00604 void test_msg_put()
00605 {
00606     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00607     Queue<int32_t, 1> queue;
00608 
00609     queue.put((int32_t *)0xE1EE7);
00610 
00611     t.start(callback(test_msg_put_thread, &queue));
00612 
00613     Thread::yield();
00614 
00615     TEST_ASSERT_EQUAL(Thread::WaitingMessagePut, t.get_state());
00616     queue.get();
00617 }
00618 
00619 /** Utility function that places some date on the stack */
00620 void use_some_stack () {
00621     volatile uint32_t stack_filler[10] = {0xDEADBEEF};
00622 }
00623 
00624 /** Testing thread with external stack memory
00625 
00626     Given external buffer is supplied as stack to a thread
00627     when the thread executes
00628     then the supplies buffer is used as a stack
00629  */
00630 void test_thread_ext_stack() {
00631     char stack[512];
00632     Thread t(osPriorityNormal, sizeof(stack), (unsigned char*)stack);
00633 
00634     memset(&stack, 0, sizeof(stack));
00635     t.start(callback(use_some_stack));
00636     t.join();
00637 
00638     /* If buffer was used as a stack it was cleared with pattern and some data were placed in it */
00639     for(unsigned i = 0; i < sizeof(stack); i++) {
00640         if (stack[i] != 0)
00641             return;
00642     }
00643 
00644     TEST_FAIL_MESSAGE("External stack was not used.");
00645 }
00646 
00647 /** Testing thread priority operations
00648 
00649     Given thread running with osPriorityNormal
00650     when new priority is set using @a set_priority
00651     then priority is changed and can be retrieved using @a get_priority
00652  */
00653 void test_thread_prio() {
00654     Thread t(osPriorityNormal, THREAD_STACK_SIZE);
00655     t.start(callback(thread_wait_signal));
00656 
00657     TEST_ASSERT_EQUAL(osPriorityNormal, t.get_priority());
00658 
00659     t.set_priority(osPriorityHigh);
00660 
00661     TEST_ASSERT_EQUAL(osPriorityHigh, t.get_priority());
00662 
00663     t.signal_set(0x1);
00664     t.join();
00665 }
00666 
00667 utest::v1::status_t test_setup(const size_t number_of_cases) {
00668     GREENTEA_SETUP(20, "default_auto");
00669     return verbose_test_setup_handler(number_of_cases);
00670 }
00671 
00672 #define DEFAULT_HANDLERS NULL,NULL,greentea_case_setup_handler,greentea_case_teardown_handler,greentea_case_failure_abort_handler
00673 
00674 // Test cases. It's spelled out rather than constructed with macro because
00675 // macros don't play nicely with the templates (extra comma).
00676 static const case_t cases[] = {
00677     {"Testing single thread", test_single_thread<increment>, DEFAULT_HANDLERS},
00678     {"Testing parallel threads", test_parallel_threads<3, increment> , DEFAULT_HANDLERS},
00679     {"Testing serial threads", test_serial_threads<10, increment> , DEFAULT_HANDLERS},
00680 
00681     {"Testing single thread with yield", test_single_thread<increment_with_yield>, DEFAULT_HANDLERS},
00682     {"Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>, DEFAULT_HANDLERS},
00683     {"Testing serial threads with yield", test_serial_threads<10, increment_with_yield>, DEFAULT_HANDLERS},
00684 
00685     {"Testing single thread with wait", test_single_thread<increment_with_wait>, DEFAULT_HANDLERS},
00686     {"Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>, DEFAULT_HANDLERS},
00687     {"Testing serial threads with wait", test_serial_threads<10, increment_with_wait>, DEFAULT_HANDLERS},
00688 
00689     {"Testing single thread with child", test_single_thread<increment_with_child>, DEFAULT_HANDLERS},
00690     {"Testing parallel threads with child", test_parallel_threads<2, increment_with_child>, DEFAULT_HANDLERS},
00691     {"Testing serial threads with child", test_serial_threads<10, increment_with_child>, DEFAULT_HANDLERS},
00692 
00693     {"Testing single thread with murder", test_single_thread<increment_with_murder>, DEFAULT_HANDLERS},
00694     {"Testing parallel threads with murder", test_parallel_threads<2, increment_with_murder>, DEFAULT_HANDLERS},
00695     {"Testing serial threads with murder", test_serial_threads<10, increment_with_murder>, DEFAULT_HANDLERS},
00696 
00697     {"Testing thread self terminate", test_self_terminate, DEFAULT_HANDLERS},
00698 
00699     {"Testing thread signals: wait", test_thread_signal<0x1, signal_wait>, DEFAULT_HANDLERS},
00700     {"Testing thread signals: timeout", test_thread_signal<0x1, signal_wait_tout>, DEFAULT_HANDLERS},
00701     {"Testing thread signals: multi-bit", test_thread_signal<0x3, signal_wait_multibit>, DEFAULT_HANDLERS},
00702     {"Testing thread signals: multi-bit timeout", test_thread_signal<0x1, signal_wait_multibit_tout>, DEFAULT_HANDLERS},
00703     {"Testing thread signals: signal clear", test_thread_signal_clr, DEFAULT_HANDLERS},
00704 
00705 
00706     {"Testing thread stack info", test_thread_stack_info, DEFAULT_HANDLERS},
00707     {"Testing thread wait", test_thread_wait, DEFAULT_HANDLERS},
00708     {"Testing thread name", test_thread_name, DEFAULT_HANDLERS},
00709 
00710     {"Testing thread states: deleted", test_deleted, DEFAULT_HANDLERS},
00711     {"Testing thread states: wait delay", test_delay, DEFAULT_HANDLERS},
00712     {"Testing thread states: wait signal", test_signal, DEFAULT_HANDLERS},
00713     {"Testing thread states: wait event flag", test_evt_flag, DEFAULT_HANDLERS},
00714     {"Testing thread states: wait mutex", test_mutex, DEFAULT_HANDLERS},
00715     {"Testing thread states: wait semaphore", test_semaphore, DEFAULT_HANDLERS},
00716     {"Testing thread states: wait message get", test_msg_get, DEFAULT_HANDLERS},
00717     {"Testing thread states: wait message put", test_msg_put, DEFAULT_HANDLERS},
00718 
00719     {"Testing thread with external stack memory", test_thread_ext_stack, DEFAULT_HANDLERS},
00720     {"Testing thread priority ops", test_thread_prio, DEFAULT_HANDLERS}
00721 
00722 };
00723 
00724 Specification specification(test_setup, cases);
00725 
00726 int main() {
00727     return !Harness::run(specification);
00728 }