exynos_omx: multi_thread: Remove hardcoded limit on the max of number of input buffer...
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos5.git] / exynos_omx / openmax / exynos_omx / osal / Exynos_OSAL_SharedMemory.c
CommitLineData
800a8d75
JC
1/*
2 *
38ef2572 3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
800a8d75
JC
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * @file Exynos_OSAL_SharedMemory.c
20 * @brief
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * Taehwan Kim (t_h.kim@samsung.com)
38ef2572 23 * @version 2.0.0
800a8d75 24 * @history
38ef2572 25 * 2012.02.20 : Create
800a8d75
JC
26 */
27
a6c8bcb6 28#include <stdbool.h>
800a8d75
JC
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <errno.h>
33#include <pthread.h>
34#include <cutils/log.h>
35#include <cutils/atomic.h>
36#include <fcntl.h>
43cea9e0 37#include <sys/mman.h>
800a8d75
JC
38
39#include "Exynos_OSAL_SharedMemory.h"
40#include "ion.h"
41
42#define EXYNOS_LOG_OFF
43#include "Exynos_OSAL_Log.h"
44
800a8d75
JC
45static int mem_cnt = 0;
46
43cea9e0
SK
47struct EXYNOS_SHAREDMEM_LIST;
48typedef struct _EXYNOS_SHAREDMEM_LIST
800a8d75 49{
43cea9e0
SK
50 OMX_U32 IONBuffer;
51 OMX_PTR mapAddr;
52 OMX_U32 allocSize;
a6c8bcb6 53 bool owner;
43cea9e0
SK
54 struct _EXYNOS_SHAREDMEM_LIST *pNextMemory;
55} EXYNOS_SHAREDMEM_LIST;
800a8d75 56
43cea9e0 57typedef struct _EXYNOS_SHARED_MEMORY
800a8d75 58{
43cea9e0
SK
59 OMX_HANDLETYPE hIONHandle;
60 EXYNOS_SHAREDMEM_LIST *pAllocMemory;
61 OMX_HANDLETYPE hSMMutex;
62} EXYNOS_SHARED_MEMORY;
800a8d75
JC
63
64
65OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open()
66{
43cea9e0
SK
67 EXYNOS_SHARED_MEMORY *pHandle = NULL;
68 ion_client IONClient = 0;
69
70 pHandle = (EXYNOS_SHARED_MEMORY *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHARED_MEMORY));
71 Exynos_OSAL_Memset(pHandle, 0, sizeof(EXYNOS_SHARED_MEMORY));
800a8d75
JC
72 if (pHandle == NULL)
73 goto EXIT;
74
75 IONClient = (OMX_HANDLETYPE)ion_client_create();
76 if (IONClient <= 0) {
77 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_client_create Error: %d", IONClient);
78 Exynos_OSAL_Free((void *)pHandle);
79 pHandle = NULL;
80 goto EXIT;
81 }
82
43cea9e0 83 pHandle->hIONHandle = IONClient;
800a8d75 84
43cea9e0 85 Exynos_OSAL_MutexCreate(&pHandle->hSMMutex);
800a8d75
JC
86
87EXIT:
88 return (OMX_HANDLETYPE)pHandle;
89}
90
91void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle)
92{
43cea9e0
SK
93 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
94 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
95 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
96 EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
97
98 if (pHandle == NULL)
99 goto EXIT;
800a8d75 100
43cea9e0
SK
101 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
102 pCurrentElement = pSMList = pHandle->pAllocMemory;
800a8d75 103
43cea9e0
SK
104 while (pCurrentElement != NULL) {
105 pDeleteElement = pCurrentElement;
106 pCurrentElement = pCurrentElement->pNextMemory;
107
108 if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize))
109 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail");
110
111 pDeleteElement->mapAddr = NULL;
112 pDeleteElement->allocSize = 0;
113
a6c8bcb6
DZ
114 if (pDeleteElement->owner)
115 ion_free(pDeleteElement->IONBuffer);
43cea9e0
SK
116 pDeleteElement->IONBuffer = 0;
117
118 Exynos_OSAL_Free(pDeleteElement);
119
120 mem_cnt--;
121 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt);
122 }
123
124 pHandle->pAllocMemory = pSMList = NULL;
125 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
126
127 Exynos_OSAL_MutexTerminate(pHandle->hSMMutex);
128 pHandle->hSMMutex = NULL;
129
130 ion_client_destroy((ion_client)pHandle->hIONHandle);
131 pHandle->hIONHandle = NULL;
800a8d75
JC
132
133 Exynos_OSAL_Free(pHandle);
134
43cea9e0 135EXIT:
800a8d75
JC
136 return;
137}
138
139OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)
140{
43cea9e0
SK
141 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
142 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
143 EXYNOS_SHAREDMEM_LIST *pElement = NULL;
144 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
145 ion_buffer IONBuffer = 0;
146 OMX_PTR pBuffer = NULL;
2590f08f
SK
147 unsigned int mask;
148 unsigned int flag;
800a8d75
JC
149
150 if (pHandle == NULL)
151 goto EXIT;
152
43cea9e0
SK
153 pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
154 Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
a6c8bcb6 155 pElement->owner = true;
800a8d75 156
2590f08f
SK
157 switch (memoryType) {
158 case SECURE_MEMORY:
159 mask = ION_HEAP_EXYNOS_CONTIG_MASK;
ce73ba18 160 flag = ION_EXYNOS_MFC_INPUT_MASK;
2590f08f
SK
161 break;
162 case NORMAL_MEMORY:
163 mask = ION_HEAP_EXYNOS_MASK;
164 flag = 0;
165 break;
166 case SYSTEM_MEMORY:
167 mask = ION_HEAP_SYSTEM_MASK;
168 flag = ION_FLAG_CACHED;
169 break;
170 default:
171 pBuffer = NULL;
172 goto EXIT;
173 break;
174 }
164d853f 175
2590f08f 176 IONBuffer = ion_alloc((ion_client)pHandle->hIONHandle, size, 0, mask, flag);
800a8d75
JC
177
178 if (IONBuffer <= 0) {
179 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_alloc Error: %d", IONBuffer);
43cea9e0 180 Exynos_OSAL_Free((OMX_PTR)pElement);
800a8d75
JC
181 goto EXIT;
182 }
183
184 pBuffer = ion_map(IONBuffer, size, 0);
43cea9e0 185 if (pBuffer == MAP_FAILED) {
800a8d75
JC
186 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_map Error");
187 ion_free(IONBuffer);
43cea9e0
SK
188 Exynos_OSAL_Free((OMX_PTR)pElement);
189 pBuffer = NULL;
800a8d75
JC
190 goto EXIT;
191 }
192
43cea9e0
SK
193 pElement->IONBuffer = IONBuffer;
194 pElement->mapAddr = pBuffer;
195 pElement->allocSize = size;
196 pElement->pNextMemory = NULL;
800a8d75 197
43cea9e0
SK
198 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
199 pSMList = pHandle->pAllocMemory;
200 if (pSMList == NULL) {
201 pHandle->pAllocMemory = pSMList = pElement;
800a8d75 202 } else {
43cea9e0
SK
203 pCurrentElement = pSMList;
204 while (pCurrentElement->pNextMemory != NULL) {
205 pCurrentElement = pCurrentElement->pNextMemory;
800a8d75 206 }
43cea9e0 207 pCurrentElement->pNextMemory = pElement;
800a8d75 208 }
43cea9e0 209 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75
JC
210
211 mem_cnt++;
212 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory alloc count: %d", mem_cnt);
213
214EXIT:
215 return pBuffer;
216}
217
218void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
219{
43cea9e0
SK
220 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
221 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
222 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
223 EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
800a8d75
JC
224
225 if (pHandle == NULL)
226 goto EXIT;
227
43cea9e0
SK
228 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
229 pSMList = pHandle->pAllocMemory;
230 if (pSMList == NULL) {
231 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75
JC
232 goto EXIT;
233 }
234
43cea9e0
SK
235 pCurrentElement = pSMList;
236 if (pSMList->mapAddr == pBuffer) {
237 pDeleteElement = pSMList;
238 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
800a8d75 239 } else {
43cea9e0
SK
240 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
241 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
242 pCurrentElement = pCurrentElement->pNextMemory;
243
244 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
245 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
246 pDeleteElement = pCurrentElement->pNextMemory;
247 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
248 } else {
249 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75
JC
250 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
251 goto EXIT;
252 }
253 }
43cea9e0 254 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75 255
43cea9e0 256 if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
800a8d75
JC
257 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail");
258 goto EXIT;
259 }
43cea9e0
SK
260 pDeleteElement->mapAddr = NULL;
261 pDeleteElement->allocSize = 0;
800a8d75 262
a6c8bcb6
DZ
263 if (pDeleteElement->owner)
264 ion_free(pDeleteElement->IONBuffer);
43cea9e0 265 pDeleteElement->IONBuffer = 0;
800a8d75 266
43cea9e0 267 Exynos_OSAL_Free(pDeleteElement);
800a8d75
JC
268
269 mem_cnt--;
270 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt);
9dfee4e5
SK
271
272EXIT:
273 return;
274}
275
276OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned int ionfd)
277{
278 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
279 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
280 EXYNOS_SHAREDMEM_LIST *pElement = NULL;
281 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
282 ion_buffer IONBuffer = 0;
283 OMX_PTR pBuffer = NULL;
284
285 if (pHandle == NULL)
286 goto EXIT;
287
288 pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
289 Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
290
291 IONBuffer = (OMX_PTR)ionfd;
292
293 if (IONBuffer <= 0) {
294 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_alloc Error: %d", IONBuffer);
295 Exynos_OSAL_Free((void*)pElement);
296 goto EXIT;
297 }
298
299 pBuffer = ion_map(IONBuffer, size, 0);
300 if (pBuffer == NULL) {
301 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_map Error");
302 ion_free(IONBuffer);
303 Exynos_OSAL_Free((void*)pElement);
304 goto EXIT;
305 }
306
307 pElement->IONBuffer = IONBuffer;
308 pElement->mapAddr = pBuffer;
309 pElement->allocSize = size;
310 pElement->pNextMemory = NULL;
311
312 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
313 pSMList = pHandle->pAllocMemory;
314 if (pSMList == NULL) {
315 pHandle->pAllocMemory = pSMList = pElement;
316 } else {
317 pCurrentElement = pSMList;
318 while (pCurrentElement->pNextMemory != NULL) {
319 pCurrentElement = pCurrentElement->pNextMemory;
320 }
321 pCurrentElement->pNextMemory = pElement;
322 }
323 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
324
325 mem_cnt++;
326 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory alloc count: %d", mem_cnt);
327
328EXIT:
329 return pBuffer;
330}
331
332void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned int ionfd)
333{
334 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
335 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
336 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
337 EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
338
339 if (pHandle == NULL)
340 goto EXIT;
341
342 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
343 pSMList = pHandle->pAllocMemory;
344 if (pSMList == NULL) {
345 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
346 goto EXIT;
347 }
348
349 pCurrentElement = pSMList;
350 if (pSMList->IONBuffer == ionfd) {
351 pDeleteElement = pSMList;
352 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
353 } else {
354 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
355 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd))
356 pCurrentElement = pCurrentElement->pNextMemory;
357
358 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
359 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) {
360 pDeleteElement = pCurrentElement->pNextMemory;
361 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
362 } else {
363 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
364 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
365 goto EXIT;
366 }
367 }
368 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
369
370 if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
371 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail");
372 goto EXIT;
373 }
374 pDeleteElement->mapAddr = NULL;
375 pDeleteElement->allocSize = 0;
376 pDeleteElement->IONBuffer = 0;
377
378 Exynos_OSAL_Free(pDeleteElement);
379
380 mem_cnt--;
381 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt);
800a8d75
JC
382
383EXIT:
384 return;
385}
386
387int Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
388{
43cea9e0
SK
389 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
390 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
391 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
392 EXYNOS_SHAREDMEM_LIST *pFindElement = NULL;
800a8d75 393 int ion_addr = 0;
43cea9e0 394 if (pHandle == NULL || pBuffer == NULL)
800a8d75
JC
395 goto EXIT;
396
43cea9e0
SK
397 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
398 pSMList = pHandle->pAllocMemory;
399 if (pSMList == NULL) {
400 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75
JC
401 goto EXIT;
402 }
403
43cea9e0
SK
404 pCurrentElement = pSMList;
405 if (pSMList->mapAddr == pBuffer) {
406 pFindElement = pSMList;
800a8d75 407 } else {
43cea9e0
SK
408 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
409 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
410 pCurrentElement = pCurrentElement->pNextMemory;
411
412 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
413 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
414 pFindElement = pCurrentElement->pNextMemory;
415 } else {
416 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
5b46229d 417 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Can not find SharedMemory");
800a8d75
JC
418 goto EXIT;
419 }
420 }
43cea9e0 421 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75 422
43cea9e0 423 ion_addr = pFindElement->IONBuffer;
800a8d75
JC
424
425EXIT:
426 return ion_addr;
427}
428
429OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr)
430{
43cea9e0
SK
431 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
432 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
433 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
434 EXYNOS_SHAREDMEM_LIST *pFindElement = NULL;
800a8d75 435 OMX_PTR pBuffer = NULL;
43cea9e0 436 if (pHandle == NULL || ion_addr == 0)
800a8d75
JC
437 goto EXIT;
438
43cea9e0
SK
439 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
440 pSMList = pHandle->pAllocMemory;
441 if (pSMList == NULL) {
442 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75
JC
443 goto EXIT;
444 }
445
43cea9e0
SK
446 pCurrentElement = pSMList;
447 if (pSMList->IONBuffer == ion_addr) {
448 pFindElement = pSMList;
800a8d75 449 } else {
43cea9e0
SK
450 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
451 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ion_addr))
452 pCurrentElement = pCurrentElement->pNextMemory;
453
454 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
455 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ion_addr)) {
456 pFindElement = pCurrentElement->pNextMemory;
457 } else {
458 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
5b46229d 459 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Can not find SharedMemory");
800a8d75
JC
460 goto EXIT;
461 }
462 }
43cea9e0 463 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
800a8d75 464
43cea9e0 465 pBuffer = pFindElement->mapAddr;
800a8d75
JC
466
467EXIT:
468 return pBuffer;
469}