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