Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Tue Aug 9 2022 00:37:14 by
1.7.2