1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file cm_array.cpp
24 //! \brief Contains Class CmDynamicArray definitions
25 //!
26
27 #include "cm_array.h"
28 #include "cm_mem.h"
29 namespace CMRT_UMD
30 {
31 /*****************************************************************************\
32
33 Function:
34 CmDynamicArray Constructor
35
36 Description:
37 Initializes the array
38
39 Input:
40 const uint32_t initSize - initial size of the array, in elements
41
42 Output:
43 none
44
45 \*****************************************************************************/
CmDynamicArray(const uint32_t initSize)46 CmDynamicArray::CmDynamicArray( const uint32_t initSize )
47 {
48 m_arrayBuffer = nullptr;
49
50 m_usedSize = 0;
51 m_actualSize = 0;
52
53 CreateArray( initSize );
54
55 }
56 /*****************************************************************************\
57
58 Function:
59 CmDynamicArray Constructor
60
61 Description:
62 Initializes the array
63
64 Input:
65 none
66
67 Output:
68 none
69
70 \*****************************************************************************/
CmDynamicArray()71 CmDynamicArray::CmDynamicArray()
72 {
73 m_arrayBuffer = nullptr;
74 m_usedSize = 0;
75 m_actualSize = 0;
76 }
77 /*****************************************************************************\
78
79 Function:
80 CmDynamicArray Destructor
81
82 Description:
83 Frees all internal dynamic memory
84
85 Input:
86 none
87
88 Output:
89 none
90
91 \*****************************************************************************/
92
~CmDynamicArray(void)93 CmDynamicArray::~CmDynamicArray( void )
94 {
95 Delete();
96 }
97
98 /*****************************************************************************\
99
100 Function:
101 CmDynamicArray::GetElement
102
103 Description:
104 Returns the element at the index in the array
105
106 Input:
107 const uint32_t index - index of element to reference
108
109 Output:
110 void* - value of element in array
111
112 \*****************************************************************************/
113
GetElement(const uint32_t index)114 void* CmDynamicArray::GetElement( const uint32_t index )
115 {
116 void* element;
117
118 if( m_arrayBuffer && IsValidIndex( index ) )
119 {
120 element = m_arrayBuffer[ index ];
121 }
122 else
123 {
124 CM_NORMALMESSAGE("Warning: Failed to get the element at the index in the array.");
125 CmSafeMemSet( &element, 0, sizeof(void*) );
126 }
127 return element;
128 }
129
130 /*****************************************************************************\
131
132 Function:
133 CmDynamicArray::SetElement
134
135 Description:
136 Sets the element at the index in the array to the given element
137
138 Input:
139 const uint32_t index - index of element to reference
140 const void* element - value of element to set
141
142 Output:
143 bool - SUCCESS or FAIL
144
145 \*****************************************************************************/
146
SetElement(const uint32_t index,const void * element)147 bool CmDynamicArray::SetElement( const uint32_t index, const void* element )
148 {
149 bool success = false;
150
151 // If the index is larger than the size of the array then grow the array
152 if( !IsValidIndex( index ) )
153 {
154 CreateArray( index + 1 );
155 }
156
157 if( m_arrayBuffer && IsValidIndex( index ) )
158 {
159 m_arrayBuffer[ index ] = (void*)element;
160 success = true;
161 }
162
163 CM_ASSERT( success );
164 return success;
165 }
166
167 /*****************************************************************************\
168
169 Function:
170 CmDynamicArray::GetSize
171
172 Description:
173 Returns the current number of elements in the array
174
175 Input:
176 void
177
178 Output:
179 uint32_t - size of the array in elements
180
181 \*****************************************************************************/
182
GetSize(void)183 uint32_t CmDynamicArray::GetSize( void )
184 {
185 const uint32_t size = m_usedSize;
186 return size;
187 }
188
189 /*****************************************************************************\
190
191 Function:
192 CmDynamicArray::Delete
193
194 Description:
195 Deletes the internal data
196
197 Input:
198 void
199
200 Output:
201 void
202
203 \*****************************************************************************/
204
Delete(void)205 void CmDynamicArray::Delete( void )
206 {
207 DeleteArray();
208 m_usedSize = 0;
209 }
210
211 /*****************************************************************************\
212
213 Function:
214 CmDynamicArray::operator=
215
216 Description:
217 Equal operator to copy an array
218
219 Input:
220 const CmDynamicArray& array - array to copy
221
222 Output:
223 *this
224
225 \*****************************************************************************/
226
operator =(const CmDynamicArray & array)227 CmDynamicArray& CmDynamicArray::operator= ( const CmDynamicArray &array )
228 {
229
230 if( array.m_arrayBuffer )
231 {
232 if( m_usedSize < array.m_usedSize )
233 {
234 CreateArray( array.m_usedSize );
235 }
236
237 if( m_arrayBuffer && ( m_usedSize >= array.m_usedSize ) )
238 {
239 for( uint32_t i = 0; i < array.m_usedSize; i++ )
240 {
241 m_arrayBuffer[i] = array.m_arrayBuffer[i];
242 }
243 }
244 }
245
246 return *this;
247 }
248
249 /*****************************************************************************\
250
251 Function:
252 CmDynamicArray::CreateArray
253
254 Description:
255 Creates the internal array structure of the specified size
256
257 Input:
258 const uint32_t size - number of elements
259
260 Output:
261 void
262
263 \*****************************************************************************/
264
CreateArray(const uint32_t size)265 void CmDynamicArray::CreateArray( const uint32_t size )
266 {
267 if( size )
268 {
269 if( size > GetMaxSize() )
270 {
271 uint32_t actualSize = GetMaxSize() * 2;
272
273 if( size > actualSize )
274 {
275 // The minimum allocation size is 32 elements, and
276 // the allocations size is in multiples of 32 elements
277 actualSize = (uint32_t)Round( Max( size, 32 ), 32 );
278 }
279
280 CM_ASSERT( actualSize >= size );
281 CM_ASSERT( actualSize > m_actualSize );
282
283 const uint32_t allocSize = actualSize * sizeof(void*);
284
285 void** arrayBuffer = MOS_NewArray(void*, allocSize);
286
287 if( arrayBuffer )
288 {
289 CmSafeMemSet( arrayBuffer, 0, allocSize );
290
291 if( m_arrayBuffer )
292 {
293 for( uint32_t i = 0; i < m_usedSize; i++ )
294 {
295 arrayBuffer[i] = m_arrayBuffer[i];
296 }
297
298 DeleteArray();
299 }
300
301 m_arrayBuffer = arrayBuffer;
302 m_actualSize = actualSize;
303 m_usedSize = size;
304 }
305 else
306 {
307 CM_ASSERTMESSAGE("Failed to create the internal array structure of the specified size.");
308 return;
309 }
310 }
311 else
312 {
313 // Update the array length
314 m_usedSize = size;
315 }
316 }
317 }
318
319 /*****************************************************************************\
320
321 Function:
322 CmDynamicArray::DeleteArray
323
324 Description:
325 Deletes the internal array structure
326
327 Input:
328 void
329
330 Output:
331 void
332
333 \*****************************************************************************/
DeleteArray(void)334 void CmDynamicArray::DeleteArray( void )
335 {
336 if( m_arrayBuffer )
337 {
338 MOS_DeleteArray(m_arrayBuffer);
339 m_arrayBuffer = nullptr;
340 }
341
342 m_actualSize = 0;
343 }
344
345 /*****************************************************************************\
346
347 Function:
348 CmDynamicArray::GetMaxSize
349
350 Description:
351 Returns the maximum number of elements in the array
352
353 Input:
354 void
355
356 Output:
357 uint32_t length
358
359 \*****************************************************************************/
GetMaxSize(void)360 uint32_t CmDynamicArray::GetMaxSize( void )
361 {
362 return m_actualSize;
363 }
364
365 /*****************************************************************************\
366
367 Function:
368 CmDynamicArray::IsValidIndex
369
370 Description:
371 Determines if the index is in the array
372
373 Input:
374 const uint32_t index
375
376 Output:
377 bool
378
379 \*****************************************************************************/
380
IsValidIndex(const uint32_t index)381 bool CmDynamicArray::IsValidIndex( const uint32_t index )
382 {
383 return ( index < GetSize() );
384 }
385
386 /*****************************************************************************\
387
388 Function:
389 CmDynamicArray::GetFirstFreeIndex()
390
391 Description:
392 Returns the index of the first free slot in the array.
393
394 Input:
395 void
396
397 Output:
398 Returns the index of the first free slot in the array.
399 If all the slots are occupied, it will return the max size of Array.
400 \*****************************************************************************/
GetFirstFreeIndex()401 uint32_t CmDynamicArray::GetFirstFreeIndex()
402 {
403 uint32_t index = 0;
404 for( index = 0; index < GetMaxSize(); index++ )
405 {
406 if( m_arrayBuffer[ index ] == nullptr)
407 { // Find the first free slot in array
408 return index;
409 }
410 }
411 return index;
412 }
413
414 /*****************************************************************************\
415
416 Function:
417 CmDynamicArray::SetElementIntoFreeSlot(const void* element)
418
419 Description:
420 Set the element into the first available slot in the array
421 If all the slots are occupied, it will expend the array first.
422
423 Input:
424 void
425
426 Output:
427
428 \*****************************************************************************/
429
SetElementIntoFreeSlot(const void * element)430 bool CmDynamicArray::SetElementIntoFreeSlot(const void* element)
431 {
432 uint32_t index = GetFirstFreeIndex();
433
434 return SetElement(index, element);
435 }
436 }