📄 resman.c
字号:
/*******************************************************************************
* Name : resman.c
* Title : Resource Manager
* Author : Dave Bartlett
* Created : 27/11/03
*
* Copyright : 2003-2004 by Imagination Technologies Limited.
* All rights reserved. No part of this software, either
* material or conceptual may be copied or distributed,
* transmitted, transcribed, stored in a retrieval system
* or translated into any human or computer language in any
* form by any means, electronic, mechanical, manual or
* other-wise, or disclosed to third parties without the
* express written permission of Imagination Technologies
* Limited, Unit 8, HomePark Industrial Estate,
* King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description : Provide resource management
*
* Platform : Generic
*
*******************************************************************************/
/******************************************************************************
Modifications :-
$Log: resman.c $
******************************************************************************/
#include "services_headers.h"
#include "sharedutils.h"
#include "resman.h"
#ifdef __linux__
/* TODO: Move this code to an environment specific directory */
#include <linux/config.h>
#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
#include <linux/modversions.h>
#define MODVERSIONS
#endif
#include <linux/sched.h>
#include <asm/hardirq.h>
static DECLARE_MUTEX(lock);
#define ACQUIRE_SYNC_OBJ do { \
if (in_interrupt()) { \
printk ("ISR cannot take RESMAN mutex\n"); \
BUG(); \
} \
else down (&lock); \
} while (0)
#define RELEASE_SYNC_OBJ up (&lock)
#else
/* FIXME */
#define ACQUIRE_SYNC_OBJ
#define RELEASE_SYNC_OBJ
#endif
#define RESMAN_SIGNATURE 0x12345678
/**************************************** Globals FIXME move to sysdata????? */
RESMAN_LIST sResList;
RESMAN_PROCESS sProcessListStart;
RESMAN_PROCESS sProcessListEnd;
#ifdef SUPPORT_POWER_STATE
PVR_POWER_STATE ePVRResmanState;
#endif
IMG_BOOL bResManAlreadyInit=IMG_FALSE;
/******************************************************** Forword references */
PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem);
PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_PROCESS psProcess,
IMG_UINT32 ui32SearchCriteria,
IMG_UINT32 ui32ResType,
IMG_PVOID pvParam,
IMG_UINT32 ui32Param,
IMG_UINT32 ui32AutoFreeLev);
PRESMAN_PROCESS FindProcess(IMG_UINT32 ui32ProcessID);
IMG_VOID SaveRestoreBuffers(IMG_BOOL bSaveBuffers);
#ifdef DEBUG
IMG_VOID ValidateResList(IMG_VOID);
#define VALIDATERESLIST() ValidateResList()
#else
#define VALIDATERESLIST()
#endif
#ifdef __linux__
#include "proc.h"
/* Return the name of the resource type specified */
static const char *
resourceType (IMG_UINT32 type)
{
switch (type)
{
case RESMAN_TYPE_ACQUIRE_DEVICE_DATA: return "Acquire Device Data"; break;
case RESMAN_TYPE_FRAMBUFMEM: return "Frambuffer Memory"; break;
case RESMAN_TYPE_PROCESS_TERM: return "Process Term"; break;
case RESMAN_TYPE_RENDERTARGET: return "Render Target"; break;
case RESMAN_TYPE_PARAMBUFF: return "Parameter buffer"; break;
case RESMAN_TYPE_CMDQUEUE: return "Command Queue"; break;
case RESMAN_TYPE_PRIMSURF: return "Primary Surface"; break;
default: return "Unknown resource"; break;
}
} // resourceType
/* Print the resources registered to a single process into the buffer
* supplied. The 'off' parameter is the offset into the buffer from which to
* print - the number of chars already in the buffer. Refer to
* env/linux/module.c */
static off_t
ResManPrintProcessResources (char * buffer, size_t size,
PRESMAN_PROCESS psProcess)
{
off_t off = 0;
/*Search resource items starting at after the first dummy item*/
PRESMAN_ITEM psCurItem = psProcess->psResItemList->psNext;
off = printAppend (buffer, size, 0,
" pid=%ld ref count=%ld\n"
" Flags pParam Param FreeFn Type\n",
psProcess->ui32ProcessID,
psProcess->ui32RefCount);
while(psCurItem->psNext)
{
off = printAppend (buffer, size, off,
" %8lx %8p %8lx %8p %s\n",
psCurItem->ui32Flags,
psCurItem->pvParam,
psCurItem->ui32Param,
psCurItem->pfnFreeResource,
resourceType(psCurItem->ui32ResType));
psCurItem = psCurItem->psNext;
}
return off;
} /* ResManPrintProcessResources */
/* Print a list of resources registered to each process. This is used by the
* proc filesystem read function to provide debug information at runtime. The
* 'off' parameter is the index into the process list from which to print
* next. Refer to env/linux/module.c */
off_t
ResManPrintAllProcessResources (char * buffer, size_t size, off_t off)
{
int n;
PRESMAN_PROCESS psProcess;
if (bResManAlreadyInit == IMG_FALSE)
return END_OF_FILE;
VALIDATERESLIST();
if (size < 80) /* not enough space for one line */
return 0;
if (!off)
return printAppend (buffer, size, 0, "Registered resources\n");
/* Find the process according to the index. */
psProcess = sResList.psProcessList->psNext;
for (n=0; psProcess->psNext && n<off-1; n++)
{
psProcess = psProcess->psNext;
}
if (!psProcess->psNext)
return END_OF_FILE;
return ResManPrintProcessResources (buffer, size, psProcess);
} /* ResManPrintAllProcessResources */
#endif // __linux__
/**************************************************************************
Function Name : ResManInit
Inputs : None
Outputs : None
Returns : None
Globals Used : sResList - sync object is init
Description : Perform one time init on the resource list
**************************************************************************/
IMG_VOID ResManInit(void)
{
if(bResManAlreadyInit == IMG_FALSE)
{
/*Acquire resource list sync object*/
ACQUIRE_SYNC_OBJ;
bResManAlreadyInit = IMG_TRUE;
/*Init list, the linked list has dummy entires at both ends*/
sProcessListStart.psResItemList = (PRESMAN_ITEM)IMG_NULL;
sProcessListEnd.psResItemList = (PRESMAN_ITEM)IMG_NULL;
sProcessListStart.ui32ProcessID = 0;
sProcessListEnd.ui32ProcessID = 0;
#ifdef DEBUG
sProcessListStart.ui32Signature = RESMAN_SIGNATURE;
sProcessListEnd.ui32Signature = RESMAN_SIGNATURE;
#endif /* DEBUG */
sProcessListStart.psPrev = (PRESMAN_PROCESS)IMG_NULL;
sProcessListStart.psNext = &sProcessListEnd;
sProcessListEnd.psPrev = &sProcessListStart;
sProcessListEnd.psNext = (PRESMAN_PROCESS)IMG_NULL;
sResList.psProcessList = &sProcessListStart;
#ifdef SUPPORT_POWER_STATE
ePVRResmanState = PVRSRV_POWER_STATE_D0;
#endif
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
/*Check resource list*/
VALIDATERESLIST();
}
return;
}
/**************************************************************************
Function Name : ResManProcessConnect
Inputs : ui32ProcID - ID of process that just connected or RESMAN_PROCESSID_FIND
to indicate the routine should find the current process ID
Outputs : None
Returns : None
Globals Used : sResList
Description : Informs the resource manager that a process has just
connected
**************************************************************************/
void ResManProcessConnect(IMG_UINT32 ui32ProcID)
{
IMG_UINT32 ui32CurProcessID;
PRESMAN_PROCESS psProcess;
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;
}
/* Check if we already have a resource list for the current process */
psProcess = FindProcess(ui32CurProcessID);
if(psProcess != IMG_NULL)
{
/* Note down that current process has made another connection */
psProcess->ui32RefCount++;
PVR_DPF((PVR_DBG_MESSAGE, "ResManProcessConnect: Process 0x%lx has just opened another handle (num %ld)", ui32CurProcessID, psProcess->ui32RefCount));
}
else
{
RESMAN_PROCESS *psDummy;
RESMAN_ITEM *psFirstItem;
RESMAN_ITEM *psLastItem;
PVR_DPF((PVR_DBG_MESSAGE, "ResManProcessConnect: Process 0x%lx has make first connection", ui32CurProcessID));
/*Create a new struct for this new process*/
if(HostAllocMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, sizeof(RESMAN_PROCESS), (IMG_VOID **)&psProcess, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "ResManProcessConnect: ERROR allocating new RESMAN process struct"));
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return;
}
#ifdef DEBUG
psProcess->ui32Signature = RESMAN_SIGNATURE;
#endif /* DEBUG */
psProcess->ui32ProcessID = ui32CurProcessID;
psProcess->ui32RefCount = 1;
/*Create empty resource list for this process*/
if(HostAllocMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, sizeof(RESMAN_ITEM) * 2, (IMG_VOID **)&psFirstItem, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "ResManProcessConnect: ERROR allocating new 2 item struct"));
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psProcess);
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return;
}
HostMemSet(psFirstItem, 0, sizeof(RESMAN_ITEM) * 2);
psLastItem = psFirstItem+1;
#ifdef DEBUG
psFirstItem->ui32Signature = RESMAN_SIGNATURE;
psLastItem->ui32Signature = RESMAN_SIGNATURE;
#endif /* DEBUG */
psFirstItem->psPrev = (PRESMAN_ITEM)IMG_NULL;
psFirstItem->psNext = psLastItem;
psLastItem->psPrev = psFirstItem;
psLastItem->psNext = (PRESMAN_ITEM)IMG_NULL;
psProcess->psResItemList = psFirstItem;
/*Insert new process struct after the dummy first entry*/
psDummy = sResList.psProcessList;
psProcess->psPrev = psDummy;
psProcess->psNext = psDummy->psNext;
psDummy->psNext->psPrev = psProcess;
psDummy->psNext = psProcess;
}
/*Check resource list*/
VALIDATERESLIST();
/*Release resource list sync object*/
RELEASE_SYNC_OBJ;
return;
}
/**************************************************************************
Function Name : ResManProcessDisconnect
Inputs : None
Outputs : None
Returns : None
Globals Used : sResList
Description : Informs the resource manager that a process has just
disconnected
**************************************************************************/
IMG_VOID ResManProcessDisconnect(IMG_UINT32 ui32ProcID)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -