xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/hw/mhw_memory_pool.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2015-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      mhw_memory_pool.cpp
24 //! \brief         This modules implements simple memory pool infrastructure for MHW
25 //!
26 #include "mhw_memory_pool.h"
27 #include "mhw_state_heap.h"
28 
29 typedef struct _MHW_MEMORY_POOL_ENTRY
30 {
31     PMHW_MEMORY_POOL_ENTRY  pNext;              //!< Next pool entry (doubled linked list)
32     PMHW_MEMORY_POOL_ENTRY  pPrev;              //!< Prev pool entry (doubled linked list)
33     PMHW_MEMORY_POOL        pPool;              //!< Pool object
34     void                    *pAllocation;        //!< Memory allocation from malloc (to be freed)
35     uint32_t                dwSize;             //!< Memory size allocated from malloc
36     void                    *pObjects;           //!< Pointer to first object in this pool entry
37     uint32_t                dwCount;            //!< Number of objects in this pool allocation
38 } MHW_MEMORY_POOL_ENTRY, *PMHW_MEMORY_POOL_ENTRY;
39 
MHW_MEMORY_POOL(uint32_t dwObjSize,uint32_t dwObjAlignment)40 MHW_MEMORY_POOL::MHW_MEMORY_POOL(uint32_t dwObjSize, uint32_t dwObjAlignment):
41     m_pFirst(nullptr),
42     m_pLast (nullptr),
43     m_dwCount(0),
44     m_dwSize(0),
45     m_dwObjSize(dwObjSize),
46     m_dwObjAlignment(dwObjAlignment),
47     m_dwObjCount(0)
48 {
49 
50 }
51 
~MHW_MEMORY_POOL()52 MHW_MEMORY_POOL::~MHW_MEMORY_POOL()
53 {
54     PMHW_MEMORY_POOL_ENTRY pEntry;
55     PMHW_MEMORY_POOL_ENTRY pNext;
56 
57     pEntry = m_pFirst;
58     while (pEntry)
59     {
60         pNext = pEntry->pNext;
61         if (pEntry->pAllocation)
62         {
63             MOS_FreeMemory(pEntry->pAllocation);
64         }
65         pEntry = pNext;
66     }
67 }
68 
69 // Allocate an array of objects to be added to the pool
Allocate(uint32_t dwObjCount)70 void  *MHW_MEMORY_POOL::Allocate(uint32_t dwObjCount)
71 {
72     uint8_t                *pObjects  = nullptr;
73     uint32_t               dwSize;
74     PMHW_MEMORY_POOL_ENTRY pEntry = nullptr;
75 
76     if (dwObjCount == 0)
77     {
78         return nullptr;
79     }
80 
81     // Calculate total size - pool entry + objects + alignments
82     dwSize = sizeof(MHW_MEMORY_POOL_ENTRY);
83     dwSize += m_dwObjSize * dwObjCount + m_dwObjAlignment;
84 
85     pEntry = (PMHW_MEMORY_POOL_ENTRY) MOS_AllocMemory(dwSize);
86     if (!pEntry)
87     {
88         return nullptr;
89     }
90     MOS_ZeroMemory(pEntry, dwSize);
91 
92     pObjects  = ((uint8_t*) pEntry) + sizeof(MHW_MEMORY_POOL_ENTRY);
93 
94     // adjust alignment if necessary
95     if ((uintptr_t(pObjects) % m_dwObjAlignment))
96     {
97         // clear out lower bits
98         pObjects = (uint8_t*)((uintptr_t)pObjects & (~(uintptr_t)(m_dwObjAlignment - 1)));
99         // add alignment
100         pObjects += m_dwObjAlignment;
101     }
102 
103     // Insert pool entry into linked list
104     pEntry->pNext = nullptr;
105     pEntry->pPrev = m_pLast;
106     m_pLast = pEntry;
107 
108     if (pEntry->pPrev) pEntry->pPrev->pNext = pEntry;
109 
110     if (!m_pFirst) m_pFirst = pEntry;
111 
112     // Setup pool entry
113     pEntry->pPool       = this;
114     pEntry->pAllocation = (void *)pEntry;
115     pEntry->dwSize      = dwSize;
116     pEntry->pObjects    = pObjects;
117     pEntry->dwCount     = dwObjCount;
118 
119     // Update pool object
120     m_dwCount++;
121     m_dwSize     += dwSize;
122     m_dwObjCount += dwObjCount;
123 
124     return pObjects;
125 }
126