xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_array.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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 }