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