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