takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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