Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : 16 : #include "AP_ExpandingArray.h" 17 : #include <AP_HAL/AP_HAL.h> 18 : 19 : #ifndef HAL_BOOTLOADER_BUILD 20 : 21 : extern const AP_HAL::HAL& hal; 22 : 23 458 : AP_ExpandingArrayGeneric::~AP_ExpandingArrayGeneric(void) 24 : { 25 : // free chunks 26 458 : for (uint16_t i=0; i<chunk_count; i++) { 27 0 : free(chunk_ptrs[i]); 28 : } 29 : // free chunks_ptrs array 30 458 : free(chunk_ptrs); 31 458 : } 32 : 33 : // expand the array by specified number of chunks, returns true on success 34 12 : bool AP_ExpandingArrayGeneric::expand(uint16_t num_chunks) 35 : { 36 : // expand chunk_ptrs array if necessary 37 12 : if (chunk_count + num_chunks >= chunk_count_max) { 38 11 : uint16_t chunk_ptr_size = chunk_count + num_chunks + chunk_ptr_increment; 39 11 : if (hal.util->available_memory() < 100U + (chunk_ptr_size * sizeof(chunk_ptr_t))) { 40 : // fail if reallocating would leave less than 100 bytes of memory free 41 0 : return false; 42 : } 43 11 : chunk_ptr_t *chunk_ptrs_new = (chunk_ptr_t*)mem_realloc((void*)chunk_ptrs, 44 11 : chunk_count_max * sizeof(chunk_ptr_t), 45 11 : chunk_ptr_size * sizeof(chunk_ptr_t)); 46 : 47 11 : if (chunk_ptrs_new == nullptr) { 48 0 : return false; 49 : } 50 : 51 : // use new pointers array 52 11 : chunk_ptrs = chunk_ptrs_new; 53 11 : chunk_count_max = chunk_ptr_size; 54 : } 55 : 56 : // allocate new chunks 57 24 : for (uint16_t i = 0; i < num_chunks; i++) { 58 12 : if (hal.util->available_memory() < 100U + (chunk_size * elem_size)) { 59 : // fail if reallocating would leave less than 100 bytes of memory free 60 0 : return false; 61 : } 62 12 : uint8_t *new_chunk = (uint8_t *)calloc(chunk_size, elem_size); 63 12 : if (new_chunk == nullptr) { 64 : // failed to allocate new chunk 65 0 : return false; 66 : } 67 12 : chunk_ptrs[chunk_count] = new_chunk; 68 12 : chunk_count++; 69 : } 70 12 : return true; 71 : } 72 : 73 : // expand to hold at least num_items 74 67 : bool AP_ExpandingArrayGeneric::expand_to_hold(uint16_t num_items) 75 : { 76 : // check if already big enough 77 67 : if (num_items <= max_items()) { 78 58 : return true; 79 : } 80 9 : uint16_t chunks_required = ((num_items - max_items()) / chunk_size) + 1; 81 9 : return expand(chunks_required); 82 : } 83 : 84 : #endif // HAL_BOOTLOADER_BUILD