in src/heap/src/HybridHeap.c [24:131]
STATUS hybridCreateHeap(PHeap pHeap, UINT32 spillRatio, UINT32 behaviorFlags, PHybridHeap* ppHybridHeap)
{
ENTERS();
STATUS retStatus = STATUS_SUCCESS;
PHybridHeap pHybridHeap = NULL;
PBaseHeap pBaseHeap = NULL;
PVOID handle = NULL;
VramInit vramInit = NULL;
VramAlloc vramAlloc = NULL;
VramFree vramFree = NULL;
VramLock vramLock = NULL;
VramUnlock vramUnlock = NULL;
VramUninit vramUninit = NULL;
VramGetMax vramGetMax = NULL;
BOOL reopenVramLibrary = ((behaviorFlags & FLAGS_REOPEN_VRAM_LIBRARY) != HEAP_FLAGS_NONE);
CHK(pHeap != NULL, STATUS_NULL_ARG);
CHK(spillRatio <= 100, STATUS_INVALID_ARG);
// Load the library.
// NOTE: The library will only be present on VRAM allocation capable devices
// We will try to load the library with the name first and then with full path
if (NULL == (handle = DLOPEN((PCHAR) VRAM_LIBRARY_NAME, RTLD_NOW | RTLD_GLOBAL)) &&
NULL == (handle = DLOPEN((PCHAR) VRAM_LIBRARY_FULL_PATH, RTLD_NOW | RTLD_GLOBAL))) {
CHK_ERR(FALSE, STATUS_HEAP_VRAM_LIB_MISSING, "Failed to load library %s with %s", VRAM_LIBRARY_NAME, DLERROR());
}
// HACK Reopening the vram library to increment the ref count, because for some unknown reason in heapRelease we
// get a SIGSEGV on DLCLOSE as the library seems to be already closed, https://jira2.amazon.com/browse/AIVPLAYERS-5111.
if (reopenVramLibrary && NULL == (handle = DLOPEN((PCHAR) VRAM_LIBRARY_NAME, RTLD_NOW | RTLD_GLOBAL)) &&
NULL == (handle = DLOPEN((PCHAR) VRAM_LIBRARY_FULL_PATH, RTLD_NOW | RTLD_GLOBAL))) {
CHK_ERR(FALSE, STATUS_HEAP_VRAM_LIB_REOPEN, "Failed to re-open library %s with %s", VRAM_LIBRARY_NAME, DLERROR());
}
// Load the functions and store the pointers
CHK_ERR(NULL != (vramInit = (VramInit) DLSYM(handle, (PCHAR) VRAM_INIT_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_INIT_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_INIT_FUNC_SYMBOL_NAME, DLERROR());
CHK_ERR(NULL != (vramAlloc = (VramAlloc) DLSYM(handle, (PCHAR) VRAM_ALLOC_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_ALLOC_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_ALLOC_FUNC_SYMBOL_NAME, DLERROR());
CHK_ERR(NULL != (vramFree = (VramFree) DLSYM(handle, (PCHAR) VRAM_FREE_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_FREE_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_FREE_FUNC_SYMBOL_NAME, DLERROR());
CHK_ERR(NULL != (vramLock = (VramLock) DLSYM(handle, (PCHAR) VRAM_LOCK_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_LOCK_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_LOCK_FUNC_SYMBOL_NAME, DLERROR());
CHK_ERR(NULL != (vramUnlock = (VramUnlock) DLSYM(handle, (PCHAR) VRAM_UNLOCK_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_UNLOCK_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_UNLOCK_FUNC_SYMBOL_NAME, DLERROR());
CHK_ERR(NULL != (vramUninit = (VramUninit) DLSYM(handle, (PCHAR) VRAM_UNINIT_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_UNINIT_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_UNINIT_FUNC_SYMBOL_NAME, DLERROR());
CHK_ERR(NULL != (vramGetMax = (VramGetMax) DLSYM(handle, (PCHAR) VRAM_GETMAX_FUNC_SYMBOL_NAME)), STATUS_HEAP_VRAM_GETMAX_FUNC_SYMBOL,
"Failed to load exported function %s with %s", VRAM_GETMAX_FUNC_SYMBOL_NAME, DLERROR());
DLOGS("Creating hybrid heap with spill ratio %d", spillRatio);
CHK_STATUS(commonHeapCreate((PHeap*) &pHybridHeap, SIZEOF(HybridHeap)));
// Set the values
pHybridHeap->pMemHeap = (PBaseHeap) pHeap;
pHybridHeap->spillRatio = (DOUBLE) spillRatio / 100;
pHybridHeap->vramInit = vramInit;
pHybridHeap->vramAlloc = vramAlloc;
pHybridHeap->vramFree = vramFree;
pHybridHeap->vramLock = vramLock;
pHybridHeap->vramUnlock = vramUnlock;
pHybridHeap->vramUninit = vramUninit;
pHybridHeap->vramGetMax = vramGetMax;
pHybridHeap->libHandle = handle;
pHybridHeap->vramInitialized = FALSE;
// Return hybrid heap
*ppHybridHeap = pHybridHeap;
// Set the function pointers
pBaseHeap = (PBaseHeap) pHybridHeap;
pBaseHeap->heapInitializeFn = hybridHeapInit;
pBaseHeap->heapReleaseFn = hybridHeapRelease;
pBaseHeap->heapGetSizeFn = commonHeapGetSize; // Use the common heap functionality
pBaseHeap->heapAllocFn = hybridHeapAlloc;
pBaseHeap->heapFreeFn = hybridHeapFree;
pBaseHeap->heapGetAllocSizeFn = hybridHeapGetAllocSize;
pBaseHeap->heapSetAllocSizeFn = hybridHeapSetAllocSize;
pBaseHeap->heapMapFn = hybridHeapMap;
pBaseHeap->heapUnmapFn = hybridHeapUnmap;
pBaseHeap->heapDebugCheckAllocatorFn = hybridHeapDebugCheckAllocator;
pBaseHeap->getAllocationSizeFn = hybridGetAllocationSize;
pBaseHeap->getAllocationHeaderSizeFn = hybridGetAllocationHeaderSize;
pBaseHeap->getAllocationFooterSizeFn = hybridGetAllocationFooterSize;
pBaseHeap->getAllocationAlignedSizeFn = hybridGetAllocationAlignedSize;
pBaseHeap->getHeapLimitsFn = hybridGetHeapLimits;
CleanUp:
if (STATUS_FAILED(retStatus)) {
if (handle != NULL) {
DLCLOSE(handle);
}
if (pHybridHeap != NULL) {
// Ensure it doesn't get closed again
pHybridHeap->libHandle = NULL;
// Base heap will be released by the common heap
pHybridHeap->pMemHeap = NULL;
hybridHeapRelease((PHeap) pHybridHeap);
}
}
LEAVES();
return retStatus;
}