📄 resman.c
字号:
{
PRESMAN_PROCESS psProcess;
IMG_UINT32 ui32CurProcessID;
ResManInit(); /* Ensure ResMan initialised */
/*Acquire resource list sync object*/
ACQUIRE_SYNC_OBJ;
/*Check resource list*/
VALIDATERESLIST();
/*Find the current process ID*/
if (ui32ProcID == RESMAN_PROCESSID_FIND)
{
ui32CurProcessID = HostGetCurrentProcessID();
}
else
{
ui32CurProcessID = ui32ProcID;
}
/* Find the process struct for the current process*/
psProcess = FindProcess(ui32CurProcessID);
if(psProcess == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR, "ResManProcessDisconnect: ERROR finding process struct for 0x%x", ui32CurProcessID));
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return;
}
/*Check if this is the last close from this habdle*/
if(--psProcess->ui32RefCount == 0)
{
PVR_DPF((PVR_DBG_MESSAGE, "ResManProcessDisconnect: Last close from process 0x%lx received", ui32CurProcessID));
/*Free all auto-freed resources in order */
FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_AUTOFREE, 0, 0, 0, RESMAN_AUTOFREE_LEV1);
FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_AUTOFREE, 0, 0, 0, RESMAN_AUTOFREE_LEV2);
FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_AUTOFREE, 0, 0, 0, RESMAN_AUTOFREE_LEV3);
FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_AUTOFREE, 0, 0, 0, RESMAN_AUTOFREE_LEV4);
FreeResourceByCriteria(psProcess, RESMAN_CRITERIA_AUTOFREE, 0, 0, 0, RESMAN_AUTOFREE_LEV5);
/*Remove the process struct from the list*/
psProcess->psPrev->psNext = psProcess->psNext;
psProcess->psNext->psPrev = psProcess->psPrev;
/*
Free the dummy item structs at front and back of item list
NOTE these were allocated with a single alloc
*/
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psProcess->psResItemList);
/* Free the process struct*/
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psProcess);
}
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return;
}
/**************************************************************************
Function Name : ResManRegisterRes
Inputs : psResItem - pointer to RESMAN_ITEM to use, if IMG_NULL then
routine will alloc memory for it
dwResType - identify what kind of resource it is
pvParam - address of resource
dwSize - size of resource
pfnFreeResource - pointer to function that frees this resource
bAutoFree - indicates if resource shuld be freed when the process closes its
last handle to PMXDXSRV
Outputs : None
Returns : On success a pointer to an opaque data structure that reprosents
the allocated resource, else IMG_NULL
Globals Used : sResList - find start of resource list and acquire list sync object
Description : Inform the resource manager that the given resource ha been
alloacted and freeing of it will be the responiblity of
the resource manager
**************************************************************************/
RESMAN_ITEM *ResManRegisterRes(RESMAN_ITEM *psResItem2Use,
IMG_UINT32 ui32ResType,
IMG_PVOID pvParam,
IMG_UINT32 ui32Param,
RESMAN_FREE_FN pfnFreeResource,
IMG_UINT32 ui32AutoFreeLev)
{
IMG_UINT32 ui32CurProcessID;
PRESMAN_ITEM psNewResItem;
PRESMAN_ITEM psDummy;
PRESMAN_PROCESS psProcess;
ResManInit(); /* Ensure ResMan initialised */
/*Acquire resource list sync object*/
ACQUIRE_SYNC_OBJ;
/*Check resource list*/
VALIDATERESLIST();
/*Find the current process ID*/
ui32CurProcessID = HostGetCurrentProcessID();
PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource Proc 0x%lx, ResType 0x%lx, pvParam 0x%lx, ui32Param 0x%lx, FreeFunc 0x%lx, ResItem buf 2 use 0x%lx", ui32CurProcessID, ui32ResType, pvParam, ui32Param, pfnFreeResource, psResItem2Use));
/*Find the process struct for the current process*/
psProcess = FindProcess(ui32CurProcessID);
if(psProcess == IMG_NULL)
{
PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: Could not find process info for process 0x%lx", ui32CurProcessID));
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return((PRESMAN_ITEM)IMG_NULL);
}
/*
We do not want multiple process terminate callbacks we the same routine.
So return ok if this is a second process terminate with the same callback routine
*/
if(ui32ResType == RESMAN_TYPE_PROCESS_TERM)
{
PRESMAN_ITEM psItem=psProcess->psResItemList;
while (psItem != IMG_NULL)
{
if (psItem->ui32ResType == RESMAN_TYPE_PROCESS_TERM && psItem->pfnFreeResource == pfnFreeResource)
{
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return(psItem);
}
psItem = psItem->psNext;
}
}
/*Allocate memory for the new resource structure if not supplied by caller*/
if(psResItem2Use == IMG_NULL)
{
if(HostAllocMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: ERROR allocating new resource item"));
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return((PRESMAN_ITEM)IMG_NULL);
}
psNewResItem->ui32Flags=0;
}
else
{
psNewResItem = psResItem2Use;
psNewResItem->ui32Flags = RESMAN_FLAGS_CALLER_ALLOCED_BUF;
}
/*Fill in details about this resource*/
#ifdef DEBUG
psNewResItem->ui32Signature = RESMAN_SIGNATURE;
#endif /* DEBUG */
PVR_ASSERT(ui32ResType != 0); /*Resource type MUST be given*/
psNewResItem->ui32ResType = ui32ResType;
psNewResItem->pvParam = pvParam;
psNewResItem->ui32Param = ui32Param;
psNewResItem->pfnFreeResource = pfnFreeResource;
psNewResItem->ui32ProcessID = ui32CurProcessID;
psNewResItem->ui32Flags |= ui32AutoFreeLev;
/*Insert new structure after dummy first entry*/
psDummy = psProcess->psResItemList;
psNewResItem->psPrev = psDummy;
psNewResItem->psNext = psDummy->psNext;
psDummy->psNext->psPrev = psNewResItem;
psDummy->psNext = psNewResItem;
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return(psNewResItem);
}
/**************************************************************************
Function Name : ResManFreeResByPtr
Inputs : psResItem - pointer to resource item to free
Outputs : None
Returns : IMG_TRUE on success, else IMG_FALSE
Globals Used : sResList -
Description : <A readable description of the purpose of this function>
**************************************************************************/
PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem)
{
PVRSRV_ERROR eRet;
PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at 0x%lx", psResItem));
/*Acquire resource list sync object*/
ACQUIRE_SYNC_OBJ;
/*Check resource list*/
VALIDATERESLIST();
/*Free resource*/
eRet = FreeResourceByPtr(psResItem);
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return(eRet);
}
/**************************************************************************
Function Name : ResManFreeResByCriteria
Inputs : ui32SearchCriteria - indicates which parameters should be used
search for resources to free
ui32ResType - identify what kind of resource to free
pvParam - address of resource to be free
ui32Param - size of resource to be free
ui32AutoFreeLev - autofree level to free
Outputs : None
Returns : PVRSRV_OK on success.
Globals Used : sResList
Description : Frees all resources that match the given criteria
that have been specified for the current process
**************************************************************************/
PVRSRV_ERROR ResManFreeResByCriteria(IMG_UINT32 ui32SearchCriteria,
IMG_UINT32 ui32ResType,
IMG_PVOID pvParam,
IMG_UINT32 ui32Param,
IMG_UINT32 ui32AutoFreeLev)
{
IMG_UINT32 ui32CurProcessID;
PRESMAN_PROCESS psProcess;
PVRSRV_ERROR eError;
ResManInit(); /* Ensure ResMan initialised */
/*Acquire resource list sync object*/
ACQUIRE_SYNC_OBJ;
/*Check resource list*/
VALIDATERESLIST();
/*Find the current process ID*/
ui32CurProcessID = HostGetCurrentProcessID();
PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: Proc 0x%lx, Criteria 0x%lx, Proc 0x%lx, Type 0x%lx, Addr 0x%lx, Size 0x%lx", ui32CurProcessID, ui32SearchCriteria, ui32ResType, pvParam, ui32Param));
/*Find the process struct for the current process*/
psProcess = FindProcess(ui32CurProcessID);
if(psProcess == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR, "ResManFreeResByCriteria: ERROR finding process struct for 0x%lx", ui32CurProcessID));
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return PVRSRV_ERROR_GENERIC;
}
/*Free resources by criteria for this process*/
eError = FreeResourceByCriteria(psProcess, ui32SearchCriteria, ui32ResType, pvParam, ui32Param, ui32AutoFreeLev);
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return eError;
}
#ifdef SUPPORT_POWER_STATE
/*----------------------------------------------------------------------------
<function>
FUNCTION : ResManSetPowerState
PURPOSE : ResManPowerState transition code
PARAMETERS : PVR_POWER_STATE ePVRState,IMG_UINT32 ui32Flags
RETURNS :
</function>
------------------------------------------------------------------------------*/
IMG_VOID ResManSetPowerState(PVR_POWER_STATE ePVRState,IMG_UINT32 ui32Flags)
{
if(ui32Flags == (PVRSRV_SEVERE_LOSS_OF_CONTEXT | PVRSRV_PRE_STATE_CHANGE_MASK)) /* Pre */
{
if((ePVRState != ePVRResmanState)&& (ePVRState==PVRSRV_POWER_STATE_D3))
{
SaveRestoreBuffers(IMG_TRUE);
}
}
if((ui32Flags & PVRSRV_PRE_STATE_CHANGE_MASK) == 0) /* Post */
{
if((ePVRResmanState == PVRSRV_POWER_STATE_D3) && (ePVRState != PVRSRV_POWER_STATE_D3))
{
SaveRestoreBuffers(IMG_FALSE);
}
ePVRResmanState=ePVRState;
}
}
#endif
/**************************************************************************
Function Name : FreeResourceByPtr
Inputs : psItem - pointer to resource item to free
Outputs : None
Returns : IMG_TRUE if resource was freed sucessfully else IMG_FALSE
Globals Used : sResList
Description : Frees a resource and move it from the list
NOTE : this function must be called with the resource
list sync object held
**************************************************************************/
PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem)
{
PVRSRV_ERROR eRet;
PVR_ASSERT(psItem != IMG_NULL);
PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE);
PVR_DPF((PVR_DBG_MESSAGE, "FreeResourceByPtr: Resource Proc 0x%lx, Type 0x%lx, Addr 0x%lx, Size 0x%lx, FnCall 0x%lx, Flags 0x%lx", HostGetCurrentProcessID(), psItem->ui32ResType, psItem->pvParam, psItem->ui32Param, psItem->pfnFreeResource, psItem->ui32Flags));
/*Remove this item from the resource list*/
psItem->psPrev->psNext = psItem->psNext;
psItem->psNext->psPrev = psItem->psPrev;
/*Release resource list sync object just in case the free routine calls the resource manager*/
RELEASE_SYNC_OBJ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -