xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/heap_manager/heap.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     heap.cpp
24 //! \brief    Implements functionalities pertaining to heaps.
25 //!
26 
27 #include "heap.h"
28 
Heap()29 Heap::Heap()
30 {
31     HEAP_FUNCTION_ENTER;
32     m_id = m_invalidId;
33 }
34 
Heap(uint32_t id)35 Heap::Heap(uint32_t id)
36 {
37     HEAP_FUNCTION_ENTER;
38     m_id = id;
39 }
40 
~Heap()41 Heap::~Heap()
42 {
43     HEAP_FUNCTION_ENTER;
44     if (m_osInterface != nullptr)
45     {
46         if (m_lockedHeap != nullptr)
47         {
48             m_osInterface->pfnUnlockResource(m_osInterface, m_resource);
49         }
50         if (!Mos_ResourceIsNull(m_resource))
51         {
52             m_osInterface->pfnFreeResource(m_osInterface, m_resource);
53             MOS_FreeMemory(m_resource);
54         }
55     }
56 }
57 
RegisterOsInterface(PMOS_INTERFACE osInterface)58 MOS_STATUS Heap::RegisterOsInterface(PMOS_INTERFACE osInterface)
59 {
60     HEAP_FUNCTION_ENTER;
61     HEAP_CHK_NULL(osInterface);
62     m_osInterface = osInterface;
63     return MOS_STATUS_SUCCESS;
64 }
65 
Allocate(uint32_t heapSize,bool keepLocked)66 MOS_STATUS Heap::Allocate(uint32_t heapSize, bool keepLocked)
67 {
68     HEAP_FUNCTION_ENTER;
69 
70     if (heapSize == 0)
71     {
72         HEAP_ASSERTMESSAGE("No size requested for heap allocation!");
73         return MOS_STATUS_INVALID_PARAMETER;
74     }
75 
76     if (m_resource != nullptr)
77     {
78         HEAP_ASSERTMESSAGE("A heap has already been allocated!");
79         return MOS_STATUS_INVALID_PARAMETER;
80     }
81 
82     m_resource = (PMOS_RESOURCE)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE));
83     HEAP_CHK_NULL(m_resource);
84     HEAP_CHK_NULL(m_osInterface);
85 
86     MOS_ALLOC_GFXRES_PARAMS allocParams;
87     memset(&allocParams, 0, sizeof(allocParams));
88     allocParams.Type = MOS_GFXRES_BUFFER;
89     allocParams.TileType = MOS_TILE_LINEAR;
90     allocParams.Format = Format_Buffer;
91     allocParams.dwBytes = heapSize;
92     allocParams.pBufName = "Heap";
93 
94     if (m_hwWriteOnly && !keepLocked)
95     {
96         allocParams.Flags.bNotLockable = true;
97         allocParams.dwMemType = MOS_MEMPOOL_DEVICEMEMORY;
98     }
99 
100     HEAP_CHK_STATUS(m_osInterface->pfnAllocateResource(
101         m_osInterface,
102         &allocParams,
103         m_resource));
104 
105     // explicit set to skip resource sync, heap resource should be used block by block
106     // driver should ensure non concurrent access the same block
107     HEAP_CHK_STATUS(m_osInterface->pfnSkipResourceSync(m_resource));
108 
109     if (keepLocked)
110     {
111         m_lockedHeap = Lock();
112         HEAP_CHK_NULL(m_lockedHeap);
113         m_keepLocked = keepLocked;
114     }
115 
116     m_size = heapSize;
117     m_freeSpace = m_size;
118 
119     return MOS_STATUS_SUCCESS;
120 }
121 
Lock()122 uint8_t* Heap::Lock()
123 {
124     HEAP_FUNCTION_ENTER_VERBOSE;
125     if (m_keepLocked)
126     {
127         return m_lockedHeap;
128     }
129 
130     if (m_osInterface == nullptr)
131     {
132         HEAP_ASSERTMESSAGE("Invalid m_osInterface(nullptr)");
133         return nullptr;
134     }
135 
136     MOS_LOCK_PARAMS lockParams;
137     memset(&lockParams, 0, sizeof(lockParams));
138     lockParams.WriteOnly = 1;
139     lockParams.NoOverWrite = 1;
140     lockParams.Uncached = 1;
141     uint8_t* pLockedResource =
142         (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, m_resource, &lockParams);
143     return pLockedResource;
144 }
145 
Dump()146 MOS_STATUS Heap::Dump()
147 {
148     return MOS_STATUS_UNIMPLEMENTED;
149 }
150 
AdjustFreeSpace(uint32_t addedSpace)151 MOS_STATUS Heap::AdjustFreeSpace(uint32_t addedSpace)
152 {
153     HEAP_FUNCTION_ENTER_VERBOSE;
154 
155     if (addedSpace + m_freeSpace > m_size ||
156         m_usedSpace < addedSpace)
157     {
158         HEAP_ASSERTMESSAGE("Provided space will not fit in the heap");
159         return MOS_STATUS_INVALID_PARAMETER;
160     }
161     m_freeSpace += addedSpace;
162     m_usedSpace -= addedSpace;
163 
164     return MOS_STATUS_SUCCESS;
165 }
166 
AdjustUsedSpace(uint32_t addedSpace)167 MOS_STATUS Heap::AdjustUsedSpace(uint32_t addedSpace)
168 {
169     HEAP_FUNCTION_ENTER_VERBOSE;
170 
171     if (addedSpace + m_usedSpace > m_size ||
172         m_freeSpace < addedSpace)
173     {
174         HEAP_ASSERTMESSAGE("Provided space will not fit in the heap");
175         return MOS_STATUS_INVALID_PARAMETER;
176     }
177 
178     if (m_freeInProgress)
179     {
180         HEAP_ASSERTMESSAGE("Heap is in the process of being freed, cannot add space as used");
181         return MOS_STATUS_INVALID_PARAMETER;
182     }
183 
184     m_freeSpace -= addedSpace;
185     m_usedSpace += addedSpace;
186 
187     return MOS_STATUS_SUCCESS;
188 }
189