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 "utest/utest.h" 00019 #include "unity/unity.h" 00020 00021 00022 #if defined(MBED_RTOS_SINGLE_THREAD) 00023 #error [NOT_SUPPORTED] test not supported 00024 #endif 00025 00026 using utest::v1::Case; 00027 00028 extern uint32_t mbed_heap_size; 00029 static const int test_timeout = 25; 00030 volatile bool thread_should_continue = true; 00031 #define NUM_THREADS 4 00032 #define THREAD_MALLOC_SIZE 100 00033 00034 #if defined(__CORTEX_A9) 00035 #define THREAD_STACK_SIZE 512 00036 #else 00037 #define THREAD_STACK_SIZE 256 00038 #endif 00039 00040 00041 void task_using_malloc(void) 00042 { 00043 void *data = NULL; 00044 00045 while (thread_should_continue) { 00046 // Repeatedly allocate and free memory 00047 data = malloc(THREAD_MALLOC_SIZE); 00048 TEST_ASSERT_NOT_NULL(data); 00049 00050 // test whole allocated memory 00051 memset(data, 0, THREAD_MALLOC_SIZE); 00052 00053 free(data); 00054 } 00055 } 00056 00057 /** Test for multithreaded heap allocations 00058 00059 Given multiple threads are started in parallel 00060 When each of the threads allocate memory 00061 Then the memory allocation succeed and @a malloc return valid memory 00062 */ 00063 void test_multithread_allocation(void) 00064 { 00065 // static stack for threads to reduce heap usage on devices with small RAM 00066 // and eliminate run out of heap memory problem 00067 uint8_t stack[NUM_THREADS][THREAD_STACK_SIZE]; 00068 00069 bool thread_alloc_failure = false; 00070 Thread *thread_list[NUM_THREADS]; 00071 int test_time = 20; 00072 00073 // Allocate threads for the test 00074 for (int i = 0; i < NUM_THREADS; i++) { 00075 thread_list[i] = new Thread(osPriorityNormal, THREAD_STACK_SIZE, stack[i]); 00076 if (NULL == thread_list[i]) { 00077 thread_alloc_failure = true; 00078 } else { 00079 thread_list[i]->start(task_using_malloc); 00080 } 00081 } 00082 00083 // Give the test time to run 00084 while (test_time--) { 00085 Thread::wait(1000); 00086 } 00087 00088 // Join and delete all threads 00089 thread_should_continue = false; 00090 for (int i = 0; i < NUM_THREADS; i++) { 00091 if (NULL != thread_list[i]) { 00092 thread_list[i]->join(); 00093 delete thread_list[i]; 00094 thread_list[i] = NULL; 00095 } 00096 } 00097 TEST_ASSERT_FALSE(thread_alloc_failure); 00098 } 00099 00100 /** Test for large heap allocation 00101 00102 Given a heap of size mbed_heap_size 00103 When try to allocate memory of size mbed_heap_size/5 (20% of whole heap) 00104 Then the memory is allocated and @a malloc return valid memory 00105 */ 00106 void test_big_allocation(void) 00107 { 00108 const uint32_t alloc_size = mbed_heap_size / 5; 00109 void *data = NULL; 00110 00111 data = malloc(alloc_size); 00112 TEST_ASSERT_NOT_NULL(data); 00113 00114 // test whole allocated memory 00115 memset(data, 0, alloc_size); 00116 00117 free(data); 00118 } 00119 00120 /** Test if allocation of zero size does not cause any undefined behaviour 00121 00122 Given a heap 00123 When try to allocate memory of size 0 00124 Then the return value of @a malloc depends on the particular library implementation 00125 (NULL or smallest possible allocation) and no undefined behaviour happens 00126 00127 @note If allocation size is zero, the return value depends on the particular library implementation 00128 (it may or may not be a null pointer), but the returned pointer shall not be dereferenced 00129 */ 00130 void test_zero_allocation(void) 00131 { 00132 void *data = NULL; 00133 00134 data = malloc(0); 00135 if(data != NULL) { 00136 free(data); 00137 } 00138 TEST_ASSERT_MESSAGE(true, "malloc(0) succeed - no undefined behaviour happens"); 00139 } 00140 00141 /** Test if free on NULL pointer does not cause any undefined behaviour 00142 00143 Given a NULL pointer 00144 When try to free it 00145 Then the function @a free does nothing and no undefined behaviour happens 00146 */ 00147 void test_null_free(void) 00148 { 00149 void *data = NULL; 00150 free(data); 00151 00152 TEST_ASSERT_MESSAGE(true, "free(NULL) succeed - no undefined behaviour happens"); 00153 } 00154 00155 // Test cases 00156 Case cases[] = { 00157 Case("Test 0 size allocation", test_zero_allocation), 00158 Case("Test NULL pointer free", test_null_free), 00159 Case("Test multithreaded allocations", test_multithread_allocation), 00160 Case("Test large allocation", test_big_allocation) 00161 }; 00162 00163 utest::v1::status_t greentea_test_setup(const size_t number_of_cases) 00164 { 00165 GREENTEA_SETUP(test_timeout, "timing_drift_auto"); 00166 return utest::v1::greentea_test_setup_handler(number_of_cases); 00167 } 00168 00169 utest::v1::Specification specification(greentea_test_setup, cases); 00170 00171 int main() 00172 { 00173 return !utest::v1::Harness::run(specification); 00174 }
Generated on Tue Jul 12 2022 14:24:26 by
