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

📄 handle.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
字号:
/* -*- c-file-style: "img" -*-
<module>
 * Name         : handle.c
 * Title        : Handle Management.
 * Author       : Marcus Shawcroft
 * Created      : 14 May 2003
 *
 * 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 :  Handle's are unique identifiers within a handle space
 *                associated with a user pointer. Handles can be tested
 *                for validity and mapped back to their associated
 *                user pointer.
 * 
 * Platform     : ALL
 *
</module>
*/

#include "pvr_debug.h"
#include "img_defs.h"
#include "services.h"
#include "hostfunc.h"
#include "handle.h"

struct _HANDLE_
{
	enum 
    {
		HDL_Idle,
		HDL_Busy
    } eState;
	union 
	{
		HDL NextFree;
		void *pUser;
	} u;
};
typedef struct _HANDLE_ HANDLE_H;

struct _HDL_SPACE_ 
{
	struct _HANDLE_ *pHandles;
	IMG_UINT32 uSize;
	IMG_UINT32 uGrow;
	HDL Free;
};

/* todo: boilerplate */
static void *
_ENV_Malloc (IMG_SIZE_T size)
{
	void * pvTmp;

	HostAllocMem( PVRSRV_HOST_PAGEABLE_HEAP, 
					 size, 
					(IMG_VOID **)&pvTmp,0);
	return pvTmp;
}

/* todo: boilerplate */
static void
_ENV_Free (void *pBase)
{
	HostFreeMem(PVRSRV_HOST_PAGEABLE_HEAP, pBase);
}

/* todo: boilerplate */
static void *
_ENV_ReallocX (void *pBase, IMG_SIZE_T uNewSize, IMG_SIZE_T uOldSize)
{
	void *pNewBase;
	pNewBase = _ENV_Malloc (uNewSize);
	if (pNewBase == IMG_NULL)
        return IMG_NULL;
	if (uNewSize > uOldSize)
		HostMemCopy (pNewBase, pBase, uOldSize);
	else
		HostMemCopy (pNewBase, pBase, uNewSize);
	_ENV_Free (pBase);
	return pNewBase;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   _InsertFreeList

	PURPOSE:    Insert a handle into a handle space free handle list.
	                	
	PARAMETERS:	In:  pHandleSpace - the handle space.
	            In:  handle - the handle.
	RETURNS:	None.
</function>
-----------------------------------------------------------------------------*/
static void
InsertFreeList (HDL_SPACE *pHandleSpace, HDL h)
{
	PVR_ASSERT (pHandleSpace != IMG_NULL);
	PVR_ASSERT (h>=0 && (IMG_UINT32)h < pHandleSpace->uSize);
	pHandleSpace->pHandles[h].eState = HDL_Idle;
	pHandleSpace->pHandles[h].u.NextFree = pHandleSpace->Free;
	pHandleSpace->Free = h;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   InsertFreeListRange

	PURPOSE:    Insert a handle range into a handle space free handle list.
	                	
	PARAMETERS:	In:  HDL_Space - the handle space
	            In:  start - the first handle in the range
	            In:  limit - the handle immediately after the range.
	RETURNS:	None.
</function>
------------------------------------------------------------------------------*/
static void
InsertFreeListRange (HDL_SPACE *pHandleSpace, HDL start, HDL limit)
{
	HDL h;
	for (h=start; h<limit; h++)
		InsertFreeList (pHandleSpace, h);
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceCreate

	PURPOSE:    Create a handle space.
	                	
	PARAMETERS:	In:  uInitialSize - initial number of handles in the handle space.
	            In:  uGrow - number of handles to grow the handle space by when
	                 handle are exhausted.
	RETURNS:	IMG_NULL or HDL_Space.
</function>
-----------------------------------------------------------------------------*/
HDL_SPACE *
HDL_SpaceCreate (IMG_UINT32 uInitialSize, IMG_UINT32 uGrow)
{
	HDL_SPACE *pHandleSpace;

	PVR_ASSERT (uInitialSize>0 && uGrow>0);
	PVR_DPF ((PVR_DBG_MESSAGE,
              "HDL_SpaceCreate (%d, %d)", uInitialSize, uGrow));
	pHandleSpace = _ENV_Malloc (sizeof (*pHandleSpace));
	if (pHandleSpace==0) return 0;
	pHandleSpace->uSize = uInitialSize;
	pHandleSpace->uGrow = uGrow;
	pHandleSpace->pHandles =
        _ENV_Malloc (pHandleSpace->uSize * sizeof (HANDLE_H));
	if (pHandleSpace->pHandles == IMG_NULL)
	{
		_ENV_Free (pHandleSpace);
		return 0;
	}
	pHandleSpace->Free = HDL_INVALID;
	InsertFreeListRange (pHandleSpace, 0, (HDL)pHandleSpace->uSize);
	return pHandleSpace;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceDelete

	PURPOSE:    Delete a handle space.
	                	
	PARAMETERS:	In:  pHandleSpace - handle space.
	RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void
HDL_SpaceDelete (HDL_SPACE *pHandleSpace)
{
	PVR_ASSERT (pHandleSpace != IMG_NULL);
	PVR_ASSERT (pHandleSpace->pHandles != IMG_NULL);

    _ENV_Free (pHandleSpace->pHandles);
	_ENV_Free (pHandleSpace);
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceAlloc

	PURPOSE:    Allocate a handle within a handle space and associate it with a
	            arbitrary user pointer.
	                	
	PARAMETERS:	In:  pHandleSpace - handle space.
	            In:  pUser - arbitrary user handle
	            Out: pHandle - receives allocated handle
	RETURNS:	IMG_TRUE Success
	            IMG_FALSE Failure
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
HDL_SpaceAlloc (HDL_SPACE *pHandleSpace, void *pUser, HDL *pHandle)
{

	PVR_ASSERT (pHandleSpace != IMG_NULL);

    PVR_DPF ((PVR_DBG_MESSAGE,
              "HDL_SpaceAlloc (hs=0x%x, user=0x%x)", pHandleSpace, pUser));

	/* If there are no free handles in the handle space then grow the
	   handle space */
	if (pHandleSpace->Free==HDL_INVALID && pHandleSpace->uGrow>0)
    {
		IMG_UINT32 uOldSize;
		IMG_UINT32 uNewSize;
		HANDLE_H *pNewHandles;

		uOldSize = pHandleSpace->uSize;
		uNewSize = uOldSize + pHandleSpace->uGrow;

		pNewHandles = _ENV_ReallocX (pHandleSpace->pHandles,
									 uNewSize * sizeof (HANDLE_H),
									 uOldSize * sizeof (HANDLE_H));
		if (pNewHandles == IMG_NULL)
			return IMG_FALSE;

		pHandleSpace->pHandles = pNewHandles;
		pHandleSpace->uSize = uNewSize;
		InsertFreeListRange (pHandleSpace, uOldSize, (HDL)pHandleSpace->uSize);
	}
	*pHandle = pHandleSpace->Free;

	PVR_ASSERT (*pHandle >= 0 && (IMG_UINT32) (*pHandle) < pHandleSpace->uSize);

	pHandleSpace->Free = pHandleSpace->pHandles[*pHandle].u.NextFree;
	pHandleSpace->pHandles[*pHandle].eState = HDL_Busy;
	pHandleSpace->pHandles[*pHandle].u.pUser = pUser;
	PVR_DPF ((PVR_DBG_MESSAGE,
              "HDL_SpaceAlloc (pHandleSpace=0x%x, user=0x%x)=%d", pHandleSpace, pUser, *pHandle));
	return IMG_TRUE;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceFree

	PURPOSE:    Free a handle within a handle space.
	                	
	PARAMETERS:	In:  pHandleSpace - handle space.
	            In:  handle - handle to free
	RETURNS:	None.
</function>
-----------------------------------------------------------------------------*/
void
HDL_SpaceFree (HDL_SPACE *pHandleSpace, HDL handle)
{
	PVR_ASSERT (pHandleSpace != IMG_NULL);
    
	PVR_DPF ((PVR_DBG_MESSAGE,
              "HDL_SpaceFree (0x%x, handle=%d)", pHandleSpace, handle));	

    if (handle>=0 && (IMG_UINT32)handle < pHandleSpace->uSize &&
        pHandleSpace->pHandles[handle].eState == HDL_Busy)
	{
		pHandleSpace->pHandles[handle].eState = HDL_Idle;
		pHandleSpace->pHandles[handle].u.NextFree = pHandleSpace->Free;
		pHandleSpace->Free = handle;
	}
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceLookup

	PURPOSE:    Lookup a handle within a handle space and return the associated
	            arbitrary user pointer.
	                	
	PARAMETERS:	In:  pHandleSpace - handle space.
	            In:  handle - handle to free
	RETURNS:	IMG_NULL if illegal handle, or associted user pointer.
</function>
-----------------------------------------------------------------------------*/
void *
HDL_SpaceLookup (HDL_SPACE *pHandleSpace, HDL handle)
{
	void *pUser = 0;
	
	PVR_ASSERT (pHandleSpace != IMG_NULL);

    PVR_DPF ((PVR_DBG_MESSAGE,
              "HDL_SpaceLookup (0x%x, handle=%d)", pHandleSpace, handle));	

    if (handle>=0 && (IMG_UINT32)handle < pHandleSpace->uSize &&
        pHandleSpace->pHandles[handle].eState == HDL_Busy)
		pUser = pHandleSpace->pHandles[handle].u.pUser;
	return pUser;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceFirstHandle

	PURPOSE:    Retreive the first allocated handle within a handle space.
	                	
	PARAMETERS:	In:  pHandleSpace - handle space.
	            Out: pHandle - receives the first handle
	RETURNS:	IMG_FALSE - there are no allocated handles in this handle space
	            IMG_TRUE - first allocated handle returned
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
HDL_SpaceFirstHandle (HDL_SPACE *pHandleSpace, HDL *pHandle)
{
	PVR_ASSERT (pHandleSpace!=IMG_NULL);
	for ((*pHandle)=0; (*pHandle)<(IMG_INT32)pHandleSpace->uSize; (*pHandle)++)
		if (pHandleSpace->pHandles[*pHandle].eState == HDL_Busy)
		{
			return IMG_TRUE;
		}
	return IMG_FALSE;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   HDL_SpaceNextHandle

	PURPOSE:    Retreive the next allocated handle within a handle space.
	                	
	PARAMETERS:	In:  pHandleSpace - handle space.
	            Out: pHandle - current handle, modified to be the next
	                 allocated handle in the handle space.
	RETURNS:	IMG_FALSE - there are no further allocated handles in this
	            handle space.
	            IMG_TRUE - next allocated handle returned.
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
HDL_SpaceNextHandle (HDL_SPACE *pHandleSpace, HDL *pHandle)
{
	PVR_ASSERT (pHandleSpace != IMG_NULL);
	for (; (*pHandle)<(int)pHandleSpace->uSize; (*pHandle)++)
		if (pHandleSpace->pHandles[*pHandle].eState == HDL_Busy)
		{
			return IMG_TRUE;
		}
	return IMG_FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -