1 /* ---------------------------------------------------------------------- 2 * Project: CMSIS DSP Library 3 * Title: ArrayMemory.cpp 4 * Description: Array Memory Manager 5 * 6 * $Date: 20. June 2019 7 * $Revision: V1.0.0 8 * 9 * Target Processor: Cortex-M cores 10 * -------------------------------------------------------------------- */ 11 /* 12 * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved. 13 * 14 * SPDX-License-Identifier: Apache-2.0 15 * 16 * Licensed under the Apache License, Version 2.0 (the License); you may 17 * not use this file except in compliance with the License. 18 * You may obtain a copy of the License at 19 * 20 * www.apache.org/licenses/LICENSE-2.0 21 * 22 * Unless required by applicable law or agreed to in writing, software 23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 * See the License for the specific language governing permissions and 26 * limitations under the License. 27 */ 28 #include "ArrayMemory.h" 29 #include <cstdlib> 30 #include <cstring> 31 #include <math.h> 32 33 namespace Client { ArrayMemory(char * ptr,size_t bufferLength,int aligned,bool tail)34 ArrayMemory::ArrayMemory(char* ptr, size_t bufferLength,int aligned, bool tail) 35 { 36 this->m_ptr=ptr; 37 this->m_currentPtr=ptr; 38 this->alignSize = aligned; 39 this->tail=tail; 40 this->m_bufferLength = bufferLength; 41 this->m_generation=0; 42 this->memError=false; 43 #if !defined(BENCHMARK) 44 memset((void*)ptr, 0, bufferLength); 45 #endif 46 } 47 48 // By default there is alignment and tail ArrayMemory(char * ptr,size_t bufferLength)49 ArrayMemory::ArrayMemory(char* ptr, size_t bufferLength) 50 { 51 this->m_ptr=ptr; 52 this->m_currentPtr=ptr; 53 // Align on 64 bits per default 54 this->alignSize = 8; 55 this->tail=true; 56 this->m_bufferLength = bufferLength; 57 this->m_generation=0; 58 this->memError=false; 59 #if !defined(BENCHMARK) 60 memset((void*)ptr, 0, bufferLength); 61 #endif 62 } 63 HasMemError()64 bool ArrayMemory::HasMemError() 65 { 66 return(this->memError); 67 } 68 getTailSize()69 size_t ArrayMemory::getTailSize() 70 { 71 if (this->tail) 72 { 73 return(16); 74 } 75 else 76 { 77 return(0); 78 } 79 } 80 NewBuffer(size_t length)81 char *ArrayMemory::NewBuffer(size_t length) 82 { 83 if (length == 0) 84 { 85 return(NULL); 86 } 87 88 size_t tailSize = 0; 89 // Add a tail of 16 bytes corresponding to the max number of lanes. 90 tailSize = this->getTailSize(); 91 92 // Compute some offset to align the new buffer to be allocated 93 if (this->alignSize > 0) 94 { 95 unsigned long offset; 96 unsigned long pad; 97 98 offset=(unsigned long)(this->m_currentPtr - this->m_ptr); 99 pad = this->alignSize*ceil(1.0*offset / (1.0*this->alignSize)) - offset; 100 //printf("new = %ld, old = %ld\n",pad,offset); 101 this->m_currentPtr += pad; 102 } 103 104 // Return NULL is no more enough memory in array 105 if (this->m_currentPtr + length + tailSize < this->m_ptr + m_bufferLength) 106 { 107 char *result=this->m_currentPtr; 108 this->m_currentPtr += length + tailSize; 109 110 return(result); 111 } 112 else 113 { 114 this->memError=true; 115 return(NULL); 116 } 117 } 118 IsTailEmpty(char * ptr,size_t length)119 bool ArrayMemory::IsTailEmpty(char *ptr, size_t length) 120 { 121 if ((ptr == NULL) || (length == 0)) 122 { 123 return(true); 124 } 125 else 126 { 127 char *p=ptr + length; 128 bool isEmpty=true; 129 130 for(unsigned long i=0; i < this->getTailSize() ; i++) 131 { 132 //printf("%d\n",p[i]); 133 if (p[i] != 0) 134 { 135 isEmpty = false; 136 } 137 } 138 return(isEmpty); 139 } 140 } 141 142 143 /** Reset memory 144 145 The full C buffer is set to 0 146 Current pointer is moved to start of buffer 147 Memory generation is incremented (which is 148 indirectly unvalidating all patterns. 149 If the patterns are not reloaded after this, they'll return NULL 150 when trying to access their pointer. 151 ) 152 153 */ FreeMemory()154 void ArrayMemory::FreeMemory() 155 { 156 #if !defined(BENCHMARK) 157 /* 158 In benchmark mode, memory is not clearer between 159 tests. It is faster when running on cycle model or RTL. 160 In benchmark mode, we don't tests so having a memory not 161 in a clean state is not a problem. 162 */ 163 memset(this->m_ptr, 0, this->m_bufferLength); 164 #endif 165 this->m_currentPtr=this->m_ptr; 166 this->m_generation++; 167 this->memError=false; 168 169 } 170 } 171