1 /*
2 * Copyright (c) 2019, 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 mos_gpucontextmgr_next.cpp
24 //! \brief Container class for the basic gpu context manager
25 //!
26
27 #include "mos_gpucontextmgr_next.h"
28 #include "mos_gpucontext_specific_next.h"
29 #include "mos_graphicsresource_specific_next.h"
30 #include "mos_context_next.h"
31 #include "mos_oca_rtlog_mgr.h"
32
GpuContextMgrNext(OsContextNext * osContext)33 GpuContextMgrNext::GpuContextMgrNext(OsContextNext *osContext)
34 {
35 MOS_OS_FUNCTION_ENTER;
36 m_initialized = false;
37
38 if (osContext)
39 {
40 m_osContext = osContext;
41 }
42 else
43 {
44 MOS_OS_ASSERTMESSAGE("Input osContext cannot be nullptr");
45 return;
46 }
47 }
48
~GpuContextMgrNext()49 GpuContextMgrNext::~GpuContextMgrNext()
50 {
51 MOS_OS_FUNCTION_ENTER;
52
53 if (m_gpuContextArrayMutex)
54 {
55 MosUtilities::MosDestroyMutex(m_gpuContextArrayMutex);
56 m_gpuContextArrayMutex = nullptr;
57 }
58 }
59
Initialize()60 MOS_STATUS GpuContextMgrNext::Initialize()
61 {
62 MOS_STATUS status = MOS_STATUS_SUCCESS;
63 m_gpuContextArrayMutex = MosUtilities::MosCreateMutex();
64 MOS_OS_CHK_NULL_RETURN(m_gpuContextArrayMutex);
65
66 MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
67 m_gpuContextMap.clear();
68 MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
69
70 m_initialized = true;
71 return status;
72 }
73
74
GetObject(OsContextNext * osContext)75 GpuContextMgrNext *GpuContextMgrNext::GetObject(
76 OsContextNext *osContext)
77 {
78 MOS_OS_FUNCTION_ENTER;
79 if (osContext == nullptr)
80 {
81 MOS_OS_ASSERTMESSAGE("Invalid input parameters!");
82 return nullptr;
83 }
84
85 MOS_STATUS status = MOS_STATUS_SUCCESS;
86 GpuContextMgrNext* pGpuContext = MOS_New(GpuContextMgrNext, osContext);
87 if (!pGpuContext)
88 {
89 return nullptr;
90 }
91 status = pGpuContext->Initialize();
92 if (MOS_FAILED(status))
93 {
94 MOS_Delete(pGpuContext);
95 return nullptr;
96 }
97 return pGpuContext;
98 }
99
CleanUp()100 void GpuContextMgrNext::CleanUp()
101 {
102 MOS_OS_FUNCTION_ENTER;
103
104 if (m_initialized)
105 {
106 DestroyAllGpuContexts();
107
108 MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
109 m_gpuContextMap.clear();
110 MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
111
112 m_initialized = false;
113 }
114
115 return;
116 }
117
ContextReuseNeeded()118 bool GpuContextMgrNext::ContextReuseNeeded()
119 {
120 MOS_OS_FUNCTION_ENTER;
121
122 // to be added after scalable design is nailed down
123 return false;
124 }
125
SelectContextToReuse()126 GpuContextNext *GpuContextMgrNext::SelectContextToReuse()
127 {
128 MOS_OS_FUNCTION_ENTER;
129
130 // to be added after scalable design is nailed down
131 return nullptr;
132 }
133
CreateGpuContext(const MOS_GPU_NODE gpuNode,CmdBufMgrNext * cmdBufMgr)134 GpuContextNext *GpuContextMgrNext::CreateGpuContext(
135 const MOS_GPU_NODE gpuNode,
136 CmdBufMgrNext * cmdBufMgr)
137 {
138 MOS_OS_FUNCTION_ENTER;
139
140 if (cmdBufMgr == nullptr && !m_osContext->IsAynchronous())
141 {
142 MOS_OS_ASSERTMESSAGE("nullptr of cmdbufmgr in normal mode. nullptr can only be applied in Async mode");
143 return nullptr;
144 }
145
146 GpuContextNext *reusedContext = nullptr;
147 if (ContextReuseNeeded())
148 {
149 reusedContext = SelectContextToReuse();
150 }
151
152 GpuContextNext *gpuContext = GpuContextSpecificNext::Create(gpuNode, cmdBufMgr, reusedContext);
153 if (gpuContext == nullptr)
154 {
155 MOS_OS_ASSERTMESSAGE("nullptr returned by GpuContext::Create.");
156 return nullptr;
157 }
158
159 MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
160
161 GPU_CONTEXT_HANDLE gpuContextHandle = 0;
162 bool found = false;
163
164 if (m_noCycledGpuCxtMgmt)
165 {
166 // new created context at the end of m_gpuContextArray.
167 gpuContextHandle = m_gpuContextHanleForNonCycledCase;
168 m_gpuContextHanleForNonCycledCase++;
169 }
170 else
171 {
172 // Directly replace nullptr with new created context in m_gpuContextArray.
173 GpuContextNext *curGpuContext = nullptr;
174 for (auto &igpu : m_gpuContextMap)
175 {
176 if (igpu.second == nullptr)
177 {
178 gpuContextHandle = igpu.first;
179 igpu.second = gpuContext;
180 found = true;
181 break;
182 }
183 }
184 if(!found)
185 {
186 gpuContextHandle = m_gpuContextMap.size();
187 }
188 }
189 gpuContext->SetGpuContextHandle(gpuContextHandle);
190
191
192 m_gpuContextMap[gpuContextHandle] = gpuContext;
193 m_gpuContextCount++;
194
195 MT_LOG5(MT_MOS_GPUCXT_CREATE, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)gpuContext,
196 MT_MOS_GPUCXT_COUNT, m_gpuContextCount, MT_MOS_GPU_NODE, gpuNode, MT_MOS_GPUCXT_HANDLE, gpuContextHandle);
197
198 MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
199
200 return gpuContext;
201 }
202
GetGpuContext(GPU_CONTEXT_HANDLE gpuContextHandle)203 GpuContextNext *GpuContextMgrNext::GetGpuContext(GPU_CONTEXT_HANDLE gpuContextHandle)
204 {
205 MOS_OS_FUNCTION_ENTER;
206
207 if (gpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE)
208 {
209 MOS_OS_ASSERTMESSAGE("Input gpucontext handle cannot be MOS_GPU_CONTEXT_INVALID_HANDLE!");
210 return nullptr;
211 }
212
213 GpuContextNext *gpuContext = nullptr;
214 MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
215 auto it = std::find_if(m_gpuContextMap.begin(), m_gpuContextMap.end(), [&](auto &curGpuCtx)
216 { return curGpuCtx.first == gpuContextHandle; });
217 if (m_gpuContextMap.end() != it)
218 {
219 gpuContext = m_gpuContextMap.at(gpuContextHandle);
220 }
221 else
222 {
223 MOS_OS_NORMALMESSAGE("Gpu context may have been deleted already!");
224 MT_LOG2(MT_MOS_GPUCXT_GET, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_HANDLE, gpuContextHandle);
225 gpuContext = nullptr;
226 }
227 MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
228 return gpuContext;
229 }
230
DestroyGpuContext(GpuContextNext * gpuContext)231 void GpuContextMgrNext::DestroyGpuContext(GpuContextNext *gpuContext)
232 {
233 MOS_OS_FUNCTION_ENTER;
234 MOS_OS_CHK_NULL_NO_STATUS_RETURN(gpuContext);
235
236 GpuContextNext *curGpuContext = nullptr;
237 bool found = false;
238
239 MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
240 auto it = std::find_if(m_gpuContextMap.begin(), m_gpuContextMap.end(), [&](auto &curGpuCtx)
241 { return curGpuCtx.second == gpuContext; });
242 if (m_gpuContextMap.end() != it)
243 {
244 found = true;
245 if (m_noCycledGpuCxtMgmt)
246 {
247 m_gpuContextMap.erase(it);
248 }
249 else
250 {
251 it->second = nullptr;
252 }
253 m_gpuContextCount--;
254 }
255
256 if (m_gpuContextCount == 0 && !m_noCycledGpuCxtMgmt)
257 {
258 m_gpuContextMap.clear(); // clear whole array
259 }
260
261 MT_LOG3(MT_MOS_GPUCXT_DESTROY, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)gpuContext, MT_MOS_GPUCXT_COUNT, m_gpuContextCount);
262
263 MosStreamState streamState = {};
264 streamState.osDeviceContext = m_osContext;
265 MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
266
267 if (found)
268 {
269 MOS_Delete(gpuContext); // delete gpu context.
270 }
271 else
272 {
273 MOS_OS_ASSERTMESSAGE("cannot find specified gpuContext in the gpucontext pool, something must be wrong");
274 MT_ERR3(MT_MOS_GPUCXT_DESTROY, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)gpuContext, MT_CODE_LINE, __LINE__);
275 }
276 }
277
DestroyAllGpuContexts()278 void GpuContextMgrNext::DestroyAllGpuContexts()
279 {
280 MOS_OS_FUNCTION_ENTER;
281
282 GpuContextNext *curGpuContext = nullptr;
283
284 MosUtilities::MosLockMutex(m_gpuContextArrayMutex);
285
286 // delete each instance in m_gpuContextArray
287 for (auto &curGpuContext : m_gpuContextMap)
288 {
289 MT_LOG2(MT_MOS_GPUCXT_DESTROY, MT_NORMAL, MT_MOS_GPUCXT_MGR_PTR, (int64_t)this, MT_MOS_GPUCXT_PTR, (int64_t)curGpuContext.second);
290 MOS_Delete(curGpuContext.second);
291 }
292
293 m_gpuContextMap.clear(); // clear whole array
294
295 MosUtilities::MosUnlockMutex(m_gpuContextArrayMutex);
296 }
297