📄 handle.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 + -