Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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