⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resman.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************
* 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 + -