summaryrefslogtreecommitdiffstats
path: root/pvr-source/services4/srvkm/common/handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'pvr-source/services4/srvkm/common/handle.c')
-rwxr-xr-xpvr-source/services4/srvkm/common/handle.c2689
1 files changed, 0 insertions, 2689 deletions
diff --git a/pvr-source/services4/srvkm/common/handle.c b/pvr-source/services4/srvkm/common/handle.c
deleted file mode 100755
index 1e26047..0000000
--- a/pvr-source/services4/srvkm/common/handle.c
+++ /dev/null
@@ -1,2689 +0,0 @@
-/*************************************************************************/ /*!
-@Title Resource Handle Manager
-@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description Provide resource handle management
-@License Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
-/* See handle.h for a description of the handle API. */
-
-/*
- * There is no locking here. It is assumed the code is used in a single
- * threaded environment. In particular, it is assumed that the code will
- * never be called from an interrupt handler.
- *
- * The implmentation supports movable handle structures, allowing the address
- * of a handle structure to change without having to fix up pointers in
- * any of the handle structures. For example, the linked list mechanism
- * used to link subhandles together uses handle array indices rather than
- * pointers to the structures themselves.
- */
-
-#include <stddef.h>
-
-#include "services_headers.h"
-#include "handle.h"
-
-#ifdef DEBUG
-#define HANDLE_BLOCK_SHIFT 2
-#else
-#define HANDLE_BLOCK_SHIFT 8
-#endif
-
-#define DIVIDE_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT)
-#define MULTIPLY_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT)
-
-#define HANDLE_BLOCK_SIZE MULTIPLY_BY_BLOCK_SIZE(1)
-#define HANDLE_SUB_BLOCK_MASK (HANDLE_BLOCK_SIZE - 1)
-#define HANDLE_BLOCK_MASK (~(HANDLE_SUB_BLOCK_MASK))
-
-#define HANDLE_HASH_TAB_INIT_SIZE 32
-
-#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount)
-
-/* Valid handles are never NULL, but handle array indices are based from 0 */
-#if defined (SUPPORT_SID_INTERFACE)
-#define INDEX_TO_HANDLE(i) ((IMG_SID)((i) + 1))
-#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(h) - 1)
-#else
-#define INDEX_TO_HANDLE(i) ((IMG_HANDLE)((IMG_UINTPTR_T)(i) + 1))
-#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(IMG_UINTPTR_T)(h) - 1)
-
-#endif
-
-#define INDEX_TO_BLOCK_INDEX(i) DIVIDE_BY_BLOCK_SIZE(i)
-#define BLOCK_INDEX_TO_INDEX(i) MULTIPLY_BY_BLOCK_SIZE(i)
-#define INDEX_TO_SUB_BLOCK_INDEX(i) ((i) & HANDLE_SUB_BLOCK_MASK)
-
-#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)]))
-#define BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i)
-
-#define INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount)
-
-#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i))
-
-#define HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h)))
-
-#define HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index)
-#define HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle))
-
-#define ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a))
-#define ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1)
-
-#define DEFAULT_MAX_HANDLE 0x7fffffffu
-#define DEFAULT_MAX_INDEX_PLUS_ONE ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE)
-
-#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0)
-
-#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount))
-
-#define SET_FLAG(v, f) ((IMG_VOID)((v) |= (f)))
-#define CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f)))
-#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0))
-
-#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f)
-
-#define SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f)
-#define CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f)
-#define TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f)
-
-#define BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
-
-#define SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
-
-#define SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED)
-
-#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
-
-#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE)
-
-#define HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE)
-
-#ifdef MIN
-#undef MIN
-#endif
-
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-
-/*
- * Linked list structure. Used for both the list head and list items.
- * Array indices, rather than pointers, are used to point to the next and
- * previous items on the list.
- */
-struct sHandleList
-{
- IMG_UINT32 ui32Prev;
- IMG_UINT32 ui32Next;
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hParent;
-#else
- IMG_HANDLE hParent;
-#endif
-};
-
-enum ePVRSRVInternalHandleFlag
-{
- INTERNAL_HANDLE_FLAG_NONE = 0x00,
- INTERNAL_HANDLE_FLAG_BATCHED = 0x01,
- INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02,
-};
-
-/* Handle structure */
-struct sHandle
-{
- /* Handle type */
- PVRSRV_HANDLE_TYPE eType;
-
- /* Pointer to the data that the handle represents */
- IMG_VOID *pvData;
-
- /*
- * When handles are on the free list, the value of the "next index
- * plus one field" has the following meaning:
- * zero - next handle is the one that follows this one,
- * nonzero - the index of the next handle is the value minus one.
- * This scheme means handle space can be initialised to all zeros.
- *
- * When this field is used to link together handles on a list
- * other than the free list, zero indicates the end of the
- * list, with nonzero the same as above.
- */
- IMG_UINT32 ui32NextIndexPlusOne;
-
- /* Internal flags */
- enum ePVRSRVInternalHandleFlag eInternalFlag;
-
- /* Flags specified when the handle was allocated */
- PVRSRV_HANDLE_ALLOC_FLAG eFlag;
-
- /* Index of this handle in the handle array */
- IMG_UINT32 ui32Index;
-
- /* List head for subhandles of this handle */
- struct sHandleList sChildren;
-
- /* List entry for sibling subhandles */
- struct sHandleList sSiblings;
-};
-
-/* Handle array index structure.
- * The handle array is an array of index structures, reallocated as the number of
- * handles increases.
- * NOTE: There is one index structure per block of handles.
- */
-struct sHandleIndex
-{
- /* Pointer to first handle structure in the block */
- struct sHandle *psHandle;
-
- /* Block allocation cookie returned from OSAllocMem for the block of handles */
- IMG_HANDLE hBlockAlloc;
-
- /* Number of free handles in block */
- IMG_UINT32 ui32FreeHandBlockCount;
-};
-
-struct _PVRSRV_HANDLE_BASE_
-{
- /* Handle returned from OSAllocMem for handle base allocation */
- IMG_HANDLE hBaseBlockAlloc;
-
- /* Handle returned from OSAllocMem for handle array allocation */
- IMG_HANDLE hArrayBlockAlloc;
-
- /* Pointer to array of pointers to handle structures */
- struct sHandleIndex *psHandleArray;
-
- /*
- * Pointer to handle hash table.
- * The hash table is used to do reverse lookups, converting data
- * pointers to handles.
- */
- HASH_TABLE *psHashTab;
-
- /* Number of free handles */
- IMG_UINT32 ui32FreeHandCount;
-
- /*
- * If purging is not enabled, this is the array index of first free
- * handle.
- * If purging is enabled, this is the index to start searching for
- * a free handle from. In this case it is usually zero, unless
- * the handle array size has been increased due to lack of
- * handles.
- */
- IMG_UINT32 ui32FirstFreeIndex;
-
- /* Maximum handle index, plus one */
- IMG_UINT32 ui32MaxIndexPlusOne;
-
- /* Total number of handles, free and allocated */
- IMG_UINT32 ui32TotalHandCount;
-
- /*
- * Index of the last free index, plus one. Not used if purging
- * is enabled.
- */
- IMG_UINT32 ui32LastFreeIndexPlusOne;
-
- /* Size of current handle batch, or zero if batching not enabled */
- IMG_UINT32 ui32HandBatchSize;
-
- /* Number of handles prior to start of current batch */
- IMG_UINT32 ui32TotalHandCountPreBatch;
-
- /* Index of first handle in batch, plus one */
- IMG_UINT32 ui32FirstBatchIndexPlusOne;
-
- /* Number of handle allocation failures in batch */
- IMG_UINT32 ui32BatchHandAllocFailures;
-
- /* Purging enabled.
- * If purging is enabled, the size of the table can be reduced
- * by removing free space at the end of the table. To make
- * purging more likely to succeed, handles are allocated as
- * far to the front of the table as possible. The first free
- * handle is found by a linear search from the start of the table,
- * and so no free handle list management is done.
- */
- IMG_BOOL bPurgingEnabled;
-};
-
-/*
- * The key for the handle hash table is an array of three elements, the
- * pointer to the resource, the resource type, and the process ID. The
- * eHandKey enumeration gives the array indices of the elements making
- * up the key.
- */
-enum eHandKey {
- HAND_KEY_DATA = 0,
- HAND_KEY_TYPE,
- HAND_KEY_PARENT,
- HAND_KEY_LEN /* Must be last item in list */
-};
-
-/*
- * Kernel handle base structure. For handles that are not allocated on
- * behalf of a particular process
- */
-PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL;
-
-/* HAND_KEY is the type of the hash table key */
-typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN];
-
-/*!
-******************************************************************************
-
- @Function HandleListInit
-
- @Description Initialise a linked list structure embedded in a handle
- structure.
-
- @Input ui32Index - index of handle in the handle array
- psList - pointer to linked list structure
- hParent - parent handle, or IMG_NULL
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(HandleListInit)
-#endif
-static INLINE
-#if defined (SUPPORT_SID_INTERFACE)
-IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_SID hParent)
-#else
-IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent)
-#endif
-{
- psList->ui32Next = ui32Index;
- psList->ui32Prev = ui32Index;
- psList->hParent = hParent;
-}
-
-/*!
-******************************************************************************
-
- @Function InitParentList
-
- @Description Initialise the children list head in a handle structure.
- The children are the subhandles of this handle.
-
- @Input psHandle - pointer to handle structure
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(InitParentList)
-#endif
-static INLINE
-IMG_VOID InitParentList(struct sHandle *psHandle)
-{
- IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle);
-
- HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent));
-}
-
-/*!
-******************************************************************************
-
- @Function InitChildEntry
-
- @Description Initialise the child list entry in a handle structure.
- The list entry is used to link together subhandles of
- a given handle.
-
- @Input psHandle - pointer to handle structure
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(InitChildEntry)
-#endif
-static INLINE
-IMG_VOID InitChildEntry(struct sHandle *psHandle)
-{
- HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL);
-}
-
-/*!
-******************************************************************************
-
- @Function HandleListIsEmpty
-
- @Description Determine whether a given linked list is empty.
-
- @Input ui32Index - index of the handle containing the list head
- psList - pointer to the list head
-
- @Return IMG_TRUE if the list is empty, IMG_FALSE if it isn't.
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(HandleListIsEmpty)
-#endif
-static INLINE
-IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList)
-{
- IMG_BOOL bIsEmpty;
-
- bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index);
-
-#ifdef DEBUG
- {
- IMG_BOOL bIsEmpty2;
-
- bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index);
- PVR_ASSERT(bIsEmpty == bIsEmpty2);
- }
-#endif
-
- return bIsEmpty;
-}
-
-#ifdef DEBUG
-/*!
-******************************************************************************
-
- @Function NoChildren
-
- @Description Determine whether a handle has any subhandles
-
- @Input psHandle - pointer to handle structure
-
- @Return IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does.
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(NoChildren)
-#endif
-static INLINE
-IMG_BOOL NoChildren(struct sHandle *psHandle)
-{
- PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle));
-
- return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren);
-}
-
-/*!
-******************************************************************************
-
- @Function NoParent
-
- @Description Determine whether a handle is a subhandle
-
- @Input psHandle - pointer to handle structure
-
- @Return IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is.
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(NoParent)
-#endif
-static INLINE
-IMG_BOOL NoParent(struct sHandle *psHandle)
-{
- if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings))
- {
- PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL);
-
- return IMG_TRUE;
- }
- else
- {
- PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL);
- }
- return IMG_FALSE;
-}
-#endif /*DEBUG*/
-/*!
-******************************************************************************
-
- @Function ParentHandle
-
- @Description Determine the parent of a handle
-
- @Input psHandle - pointer to handle structure
-
- @Return Parent handle, or IMG_NULL if the handle is not a subhandle.
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(ParentHandle)
-#endif
-static INLINE
-#if defined (SUPPORT_SID_INTERFACE)
-IMG_SID ParentHandle(struct sHandle *psHandle)
-#else
-IMG_HANDLE ParentHandle(struct sHandle *psHandle)
-#endif
-{
- return psHandle->sSiblings.hParent;
-}
-
-/*
- * The LIST_PTR_FROM_INDEX_AND_OFFSET macro is used to generate either a
- * pointer to the subhandle list head, or a pointer to the linked list
- * structure of an item on a subhandle list.
- * The list head is itself on the list, but is at a different offset
- * in the handle structure to the linked list structure for items on
- * the list. The two linked list structures are differentiated by
- * the third parameter, containing the parent index. The parent field
- * in the list head structure references the handle structure that contains
- * it. For items on the list, the parent field in the linked list structure
- * references the parent handle, which will be different from the handle
- * containing the linked list structure.
- */
-#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \
- ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo))))
-
-/*!
-******************************************************************************
-
- @Function HandleListInsertBefore
-
- @Description Insert a handle before a handle currently on the list.
-
- @Input ui32InsIndex - index of handle to be inserted after
- psIns - pointer to handle structure to be inserted after
- uiParentOffset - offset to list head struct in handle structure
- ui32EntryIndex - index of handle to be inserted
- psEntry - pointer to handle structure of item to be inserted
- uiEntryOffset - offset of list item struct in handle structure
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(HandleListInsertBefore)
-#endif
-static INLINE
-IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex)
-{
- /* PRQA S 3305 7 */ /*override stricter alignment warning */
- struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset);
-
- PVR_ASSERT(psEntry->hParent == IMG_NULL);
- PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next);
- PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(ui32ParentIndex));
-
- psEntry->ui32Prev = psIns->ui32Prev;
- psIns->ui32Prev = ui32EntryIndex;
- psEntry->ui32Next = ui32InsIndex;
- psPrevIns->ui32Next = ui32EntryIndex;
-
- psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex);
-}
-
-/*!
-******************************************************************************
-
- @Function AdoptChild
-
- @Description Assign a subhandle to a handle
-
- @Input psParent - pointer to handle structure of parent handle
- psChild - pointer to handle structure of child subhandle
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(AdoptChild)
-#endif
-static INLINE
-IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild)
-{
- IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psParent->sChildren.hParent);
-
- PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent));
-
- HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent);
-
-}
-
-/*!
-******************************************************************************
-
- @Function HandleListRemove
-
- @Description Remove a handle from a list
-
- @Input ui32EntryIndex - index of handle to be removed
- psEntry - pointer to handle structure of item to be removed
- uiEntryOffset - offset of list item struct in handle structure
- uiParentOffset - offset to list head struct in handle structure
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(HandleListRemove)
-#endif
-static INLINE
-IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset)
-{
- if (!HandleListIsEmpty(ui32EntryIndex, psEntry))
- {
- /* PRQA S 3305 3 */ /*override stricter alignment warning */
- struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
- struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset);
-
- /*
- * The list head is on the list, and we don't want to
- * remove it.
- */
- PVR_ASSERT(psEntry->hParent != IMG_NULL);
-
- psPrev->ui32Next = psEntry->ui32Next;
- psNext->ui32Prev = psEntry->ui32Prev;
-
- HandleListInit(ui32EntryIndex, psEntry, IMG_NULL);
- }
-}
-
-/*!
-******************************************************************************
-
- @Function UnlinkFromParent
-
- @Description Remove a subhandle from its parents list
-
- @Input psHandle - pointer to handle structure of child subhandle
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(UnlinkFromParent)
-#endif
-static INLINE
-IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
-{
- HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren));
-}
-
-/*!
-******************************************************************************
-
- @Function HandleListIterate
-
- @Description Iterate over the items in a list
-
- @Input psHead - pointer to list head
- uiParentOffset - offset to list head struct in handle structure
- uiEntryOffset - offset of list item struct in handle structure
- pfnIterFunc - function to be called for each handle in the list
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(HandleListIterate)
-#endif
-static INLINE
-PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
-{
- IMG_UINT32 ui32Index;
- IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psHead->hParent);
-
- PVR_ASSERT(psHead->hParent != IMG_NULL);
-
- /*
- * Follow the next chain from the list head until we reach
- * the list head again, which signifies the end of the list.
- */
- for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; )
- {
- struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
- /* PRQA S 3305 2 */ /*override stricter alignment warning */
- struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset);
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(psEntry->hParent == psHead->hParent);
- /*
- * Get the next index now, in case the list item is
- * modified by the iteration function.
- */
- ui32Index = psEntry->ui32Next;
-
- eError = (*pfnIterFunc)(psBase, psHandle);
- if (eError != PVRSRV_OK)
- {
- return eError;
- }
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function IterateOverChildren
-
- @Description Iterate over the subhandles of a parent handle
-
- @Input psParent - pointer to parent handle structure
- pfnIterFunc - function to be called for each subhandle
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(IterateOverChildren)
-#endif
-static INLINE
-PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *))
-{
- return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc);
-}
-
-/*!
-******************************************************************************
-
- @Function GetHandleStructure
-
- @Description Get the handle structure for a given handle
-
- @Input psBase - pointer to handle base structure
- ppsHandle - location to return pointer to handle structure
- hHandle - handle from client
- eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the
- handle type is not to be checked.
-
- @Output ppsHandle - points to a pointer to the handle structure
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(GetHandleStructure)
-#endif
-static INLINE
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
-#else
-PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
-#endif
-{
- IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle);
- struct sHandle *psHandle;
-
- /* Check handle index is in range */
- if (!INDEX_IS_VALID(psBase, ui32Index))
- {
- PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount));
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
- }
-
- psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index);
- if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE)
- {
- PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index));
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
- }
-
- /*
- * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function,
- * check handle is of the correct type.
- */
- if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType)
- {
- PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType));
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
- }
-
- /* Return the handle structure */
- *ppsHandle = psHandle;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function ParentIfPrivate
-
- @Description Return the parent handle if the handle was allocated
- with PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return
- IMG_NULL
-
- @Input psHandle - pointer to handle
-
- @Return Parent handle, or IMG_NULL
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(ParentIfPrivate)
-#endif
-static INLINE
-#if defined (SUPPORT_SID_INTERFACE)
-IMG_SID ParentIfPrivate(struct sHandle *psHandle)
-#else
-IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle)
-#endif
-{
- return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
- ParentHandle(psHandle) : IMG_NULL;
-}
-
-/*!
-******************************************************************************
-
- @Function InitKey
-
- @Description Initialise a hash table key for the current process
-
- @Input psBase - pointer to handle base structure
- aKey - pointer to key
- pvData - pointer to the resource the handle represents
- eType - type of resource
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(InitKey)
-#endif
-static INLINE
-#if defined (SUPPORT_SID_INTERFACE)
-IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
-#else
-IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
-#endif
-{
- PVR_UNREFERENCED_PARAMETER(psBase);
-
- aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData;
- aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType;
- aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent;
-}
-
-/*!
-******************************************************************************
-
- @Function ReallocHandleArray
-
- @Description Reallocate the handle array
-
- @Input psBase - handle base.
- phBlockAlloc - pointer to block allocation handle.
- ui32NewCount - new handle count
- ui32OldCount - old handle count
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-static
-PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount)
-{
- struct sHandleIndex *psOldArray = psBase->psHandleArray;
- IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc;
- IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount;
- struct sHandleIndex *psNewArray = IMG_NULL;
- IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL;
- PVRSRV_ERROR eError;
- PVRSRV_ERROR eReturn = PVRSRV_OK;
- IMG_UINT32 ui32Index;
-
- if (ui32NewCount == ui32OldCount)
- {
- return PVRSRV_OK;
- }
-
- if (ui32NewCount != 0 && !psBase->bPurgingEnabled &&
- ui32NewCount < ui32OldCount)
- {
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) ||
- ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0))
- {
- PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0);
- PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0);
-
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- if (ui32NewCount != 0)
- {
- /* Allocate new handle array */
- eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
- HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
- (IMG_VOID **)&psNewArray,
- &hNewArrayBlockAlloc,
- "Memory Area");
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError));
- eReturn = eError;
- goto error;
- }
-
- if (ui32OldCount != 0)
- {
- OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex));
- }
- }
-
- /*
- * If the new handle array is smaller than the old one, free
- * unused handle structures
- */
- for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE)
- {
- struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index);
-
- eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
- psIndex->psHandle,
- psIndex->hBlockAlloc);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
- }
- }
-
- /*
- * If the new handle array is bigger than the old one, allocate
- * new handle structures
- */
- for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
- {
- /* PRQA S 0505 1 */ /* psNewArray is never NULL, see assert earlier */
- struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
-
- eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
- sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
- (IMG_VOID **)&psIndex->psHandle,
- &psIndex->hBlockAlloc,
- "Memory Area");
- if (eError != PVRSRV_OK)
- {
- psIndex->psHandle = IMG_NULL;
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError));
- eReturn = eError;
- }
- else
- {
- IMG_UINT32 ui32SubIndex;
-
- psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE;
-
- for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++)
- {
- struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex;
-
-
- psHandle->ui32Index = ui32SubIndex + ui32Index;
- psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
- psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
- psHandle->ui32NextIndexPlusOne = 0;
- }
- }
- }
- if (eReturn != PVRSRV_OK)
- {
- goto error;
- }
-
-#ifdef DEBUG_MAX_HANDLE_COUNT
- /* Force handle failure to test error exit code */
- if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT)
- {
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT));
- eReturn = PVRSRV_ERROR_OUT_OF_MEMORY;
- goto error;
- }
-#endif
-
- if (psOldArray != IMG_NULL)
- {
- /* Free old handle array */
- eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex),
- psOldArray,
- hOldArrayBlockAlloc);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError));
- }
- }
-
- psBase->psHandleArray = psNewArray;
- psBase->hArrayBlockAlloc = hNewArrayBlockAlloc;
- psBase->ui32TotalHandCount = ui32NewCount;
-
- if (ui32NewCount > ui32OldCount)
- {
- /* Check for wraparound */
- PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount);
-
- /* PRQA S 3382 1 */ /* ui32NewCount always > ui32OldCount */
- psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount);
-
- /*
- * If purging is enabled, there is no free handle list
- * management, but as an optimization, when allocating
- * new handles, we use ui32FirstFreeIndex to point to
- * the first handle in a newly allocated block.
- */
- if (psBase->ui32FirstFreeIndex == 0)
- {
- PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
-
- psBase->ui32FirstFreeIndex = ui32OldCount;
- }
- else
- {
- if (!psBase->bPurgingEnabled)
- {
- PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0);
- PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
-
- INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1;
- }
- }
-
- if (!psBase->bPurgingEnabled)
- {
- psBase->ui32LastFreeIndexPlusOne = ui32NewCount;
- }
- }
- else
- {
- PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled);
- PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount);
- PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount);
-
- /* PRQA S 3382 1 */ /* ui32OldCount always >= ui32NewCount */
- psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount);
-
- if (ui32NewCount == 0)
- {
- psBase->ui32FirstFreeIndex = 0;
- psBase->ui32LastFreeIndexPlusOne = 0;
- }
- }
-
- PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount);
-
- return PVRSRV_OK;
-
-error:
- PVR_ASSERT(eReturn != PVRSRV_OK);
-
- if (psNewArray != IMG_NULL)
- {
- /* Free any new handle structures that were allocated */
- for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE)
- {
- struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index);
- if (psIndex->psHandle != IMG_NULL)
- {
- eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(struct sHandle) * HANDLE_BLOCK_SIZE,
- psIndex->psHandle,
- psIndex->hBlockAlloc);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError));
- }
- }
- }
-
- /* Free new handle array */
- eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex),
- psNewArray,
- hNewArrayBlockAlloc);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError));
- }
- }
-
- return eReturn;
-}
-
-/*!
-******************************************************************************
-
- @Function FreeHandleArray
-
- @Description Frees the handle array.
- The memory containing the array of handle structure
- pointers is deallocated.
-
- @Input psBase - pointer to handle base structure
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase)
-{
- return ReallocHandleArray(psBase, 0);
-}
-
-/*!
-******************************************************************************
-
- @Function FreeHandle
-
- @Description Free a handle structure.
-
- @Input psBase - pointer to handle base structure
- psHandle - pointer to handle structure
-
- @Return PVRSRV_OK or PVRSRV_ERROR
-
-******************************************************************************/
-static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle)
-{
- HAND_KEY aKey;
- IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle);
- PVRSRV_ERROR eError;
-
- /*
- * If a handle allocated in batch mode is freed whilst still
- * in batch mode, the type is set to PVRSRV_HANDLE_TYPE_NONE further
- * down, to indicate the handle will not be used, but not actually
- * freed. The Free is completed when this function is called a
- * second time as part of the batch commit or release.
- */
-
- InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle));
-
- if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
- {
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hHandle;
- hHandle = (IMG_SID) HASH_Remove_Extended(psBase->psHashTab, aKey);
-#else
- IMG_HANDLE hHandle;
- hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey);
-
-#endif
-
- PVR_ASSERT(hHandle != IMG_NULL);
- PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index));
- PVR_UNREFERENCED_PARAMETER(hHandle);
- }
-
- /* Unlink handle from parent */
- UnlinkFromParent(psBase, psHandle);
-
- /* Free children */
- eError = IterateOverChildren(psBase, psHandle, FreeHandle);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError));
- return eError;
- }
-
- /*
- * Clear the type here, so that a handle can no longer be looked
- * up if it is only partially freed.
- */
- psHandle->eType = PVRSRV_HANDLE_TYPE_NONE;
-
- if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
- {
- /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */
- SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle);
- /*
- * If the handle was allocated in batch mode, delay the free
- * until the batch commit or release.
- */
- return PVRSRV_OK;
- }
-
- /* No free list management if purging is enabled */
- if (!psBase->bPurgingEnabled)
- {
- if (psBase->ui32FreeHandCount == 0)
- {
- PVR_ASSERT(psBase->ui32FirstFreeIndex == 0);
- PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0);
-
- psBase->ui32FirstFreeIndex = ui32Index;
- }
- else
- {
- /*
- * Put the handle pointer on the end of the the free
- * handle pointer linked list.
- */
- PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0);
- PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0);
- INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1;
- }
-
- PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0);
-
- /* Update the end of the free handle linked list */
- psBase->ui32LastFreeIndexPlusOne = ui32Index + 1;
- }
-
- psBase->ui32FreeHandCount++;
- INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++;
-
- PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE);
-
-#ifdef DEBUG
- {
- IMG_UINT32 ui32BlockedIndex;
- IMG_UINT32 ui32FreeHandCount = 0;
-
- for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
- {
- ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex);
- }
-
- PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount);
- }
-#endif
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function FreeAllHandles
-
- @Description Free all handles for a given handle base
-
- @Input psBase - pointer to handle base structure
-
- @Return PVRSRV_OK or PVRSRV_ERROR
-
-******************************************************************************/
-static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase)
-{
- IMG_UINT32 i;
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
- {
- return eError;
- }
-
- for (i = 0; i < psBase->ui32TotalHandCount; i++)
- {
- struct sHandle *psHandle;
-
- psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, i);
-
- if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE)
- {
- eError = FreeHandle(psBase, psHandle);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError));
- break;
- }
-
- /* Break out of loop if all the handles free */
- if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount)
- {
- break;
- }
- }
- }
-
- return eError;
-}
-
-/*!
-******************************************************************************
-
- @Function FreeHandleBase
-
- @Description Free a handle base.
-
- @Input psHandleBase - pointer to handle base
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
-{
- PVRSRV_ERROR eError;
-
- if (HANDLES_BATCHED(psBase))
- {
- PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch"));
- PVRSRVReleaseHandleBatch(psBase);
- }
-
- /* Free the handle array */
- eError = FreeAllHandles(psBase);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError));
- return eError;
- }
-
- /* Free the handle array */
- eError = FreeHandleArray(psBase);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError));
- return eError;
- }
-
- if (psBase->psHashTab != IMG_NULL)
- {
- /* Free the hash table */
- HASH_Delete(psBase->psHashTab);
- }
-
- eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(*psBase),
- psBase,
- psBase->hBaseBlockAlloc);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError));
- return eError;
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function FindHandle
-
- @Description Find handle corresponding to a resource pointer
-
- @Input psBase - pointer to handle base structure
- pvData - pointer to resource to be associated with the handle
- eType - the type of resource
-
- @Return the handle, or IMG_NULL if not found
-
-******************************************************************************/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(FindHandle)
-#endif
-static INLINE
-#if defined (SUPPORT_SID_INTERFACE)
-IMG_SID FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent)
-#else
-IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent)
-#endif
-{
- HAND_KEY aKey;
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- InitKey(aKey, psBase, pvData, eType, hParent);
-
-#if defined (SUPPORT_SID_INTERFACE)
- return (IMG_SID) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
-#else
- return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
-#endif
-}
-
-/*!
-******************************************************************************
-
- @Function IncreaseHandleArraySize
-
- @Description Allocate some more free handles
-
- @Input psBase - pointer to handle base structure
- ui32Delta - number of new handles required
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta)
-{
- PVRSRV_ERROR eError;
- IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta);
- IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted;
-
- PVR_ASSERT(ui32Delta != 0);
-
- /*
- * Check new count against max handle index, and check for wrap around.
- */
- if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount)
- {
- ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne;
-
- ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount;
-
- if (ui32DeltaAdjusted < ui32Delta)
- {
- PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- }
-
- PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta);
-
- /* Realloc handle pointer array */
- eError = ReallocHandleArray(psBase, ui32NewTotalHandCount);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError));
- return eError;
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function EnsureFreeHandles
-
- @Description Ensure there are enough free handles
-
- @Input psBase - pointer to handle base structure
- ui32Free - number of free handles required
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free)
-{
- PVRSRV_ERROR eError;
-
- if (ui32Free > psBase->ui32FreeHandCount)
- {
- IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount;
- eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError));
-
- return eError;
- }
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function AllocHandle
-
- @Description Allocate a new handle
-
- @Input phHandle - location for new handle
- pvData - pointer to resource to be associated with the handle
- eType - the type of resource
- hParent - parent handle or IMG_NULL
-
- @Output phHandle - points to new handle
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
-#else
-static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
-#endif
-{
- IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE;
- struct sHandle *psNewHandle = IMG_NULL;
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hHandle;
-#else
- IMG_HANDLE hHandle;
-#endif
- HAND_KEY aKey;
- PVRSRV_ERROR eError;
-
- /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
- PVR_ASSERT(psBase != IMG_NULL);
- PVR_ASSERT(psBase->psHashTab != IMG_NULL);
-
- if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
- {
- /* Handle must not already exist */
- PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL);
- }
-
- if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase))
- {
- PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize));
- }
-
- /* Ensure there is a free handle */
- eError = EnsureFreeHandles(psBase, 1);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError));
- return eError;
- }
- PVR_ASSERT(psBase->ui32FreeHandCount != 0);
-
- if (!psBase->bPurgingEnabled)
- {
- /* Array index of first free handle */
- ui32NewIndex = psBase->ui32FirstFreeIndex;
-
- /* Get handle array entry */
- psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
- }
- else
- {
- IMG_UINT32 ui32BlockedIndex;
-
- /*
- * If purging is enabled, we always try to allocate handles
- * at the front of the array, to increase the chances that
- * the size of the handle array can be reduced by a purge.
- * No linked list of free handles is kept; we search for
- * free handles as required.
- */
-
- /*
- * ui32FirstFreeIndex should only be set when a new batch of
- * handle structures is allocated, and should always be a
- * multiple of the block size.
- */
- PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0);
-
- for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE)
- {
- struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex);
-
- if (psIndex->ui32FreeHandBlockCount == 0)
- {
- continue;
- }
-
- for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++)
- {
- psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex);
- if (HANDLE_STRUCT_IS_FREE(psNewHandle))
- {
- break;
- }
- }
- }
- psBase->ui32FirstFreeIndex = 0;
- PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount);
- }
- PVR_ASSERT(psNewHandle != IMG_NULL);
-
- /* Handle to be returned to client */
- hHandle = INDEX_TO_HANDLE(ui32NewIndex);
-
- /*
- * If a data pointer can be associated with multiple handles, we
- * don't put the handle in the hash table, as the data pointer
- * may not map to a unique handle
- */
- if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
- {
- /* Initialise hash key */
- InitKey(aKey, psBase, pvData, eType, hParent);
-
- /* Put the new handle in the hash table */
- if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle))
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table"));
-
- return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
- }
- }
-
- psBase->ui32FreeHandCount--;
-
- PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE);
- PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0);
-
- INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--;
-
- /* No free list management if purging is enabled */
- if (!psBase->bPurgingEnabled)
- {
- /* Check whether the last free handle has been allocated */
- if (psBase->ui32FreeHandCount == 0)
- {
- PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex);
- PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1));
-
- psBase->ui32LastFreeIndexPlusOne = 0;
- psBase->ui32FirstFreeIndex = 0;
- }
- else
- {
- /*
- * Update the first free handle index.
- * If the "next free index plus one" field in the new
- * handle structure is zero, the next free index is
- * the index of the new handle plus one. This
- * convention has been adopted to simplify the
- * initialisation of freshly allocated handle
- * space.
- */
- psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ?
- ui32NewIndex + 1 :
- psNewHandle->ui32NextIndexPlusOne - 1;
- }
- }
-
- /* Initialise the newly allocated handle */
- PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex);
-
- /* PRQA S 0505 1 */ /* psNewHandle is never NULL, see assert earlier */
- psNewHandle->eType = eType;
- psNewHandle->pvData = pvData;
- psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE;
- psNewHandle->eFlag = eFlag;
-
- InitParentList(psNewHandle);
-#if defined(DEBUG)
- PVR_ASSERT(NoChildren(psNewHandle));
-#endif
-
- InitChildEntry(psNewHandle);
-#if defined(DEBUG)
- PVR_ASSERT(NoParent(psNewHandle));
-#endif
-
- if (HANDLES_BATCHED(psBase))
- {
- /* Add handle to batch list */
- psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
-
- psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1;
-
- /* PRQA S 1474 1 */ /* ignore warnings about enum types being modified */
- SET_BATCHED_HANDLE(psNewHandle);
- }
- else
- {
- psNewHandle->ui32NextIndexPlusOne = 0;
- }
-
- /* Return the new handle to the client */
- *phHandle = hHandle;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVAllocHandle
-
- @Description Allocate a handle
-
- @Input phHandle - location for new handle
- pvData - pointer to resource to be associated with the handle
- eType - the type of resource
-
- @Output phHandle - points to new handle
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
-#else
-PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag)
-#endif
-{
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hHandle;
-#else
- IMG_HANDLE hHandle;
-#endif
- PVRSRV_ERROR eError;
-
-#if defined (SUPPORT_SID_INTERFACE)
- *phHandle = 0;
-#else
- *phHandle = IMG_NULL;
-#endif
-
- if (HANDLES_BATCHED(psBase))
- {
- /*
- * Increment the counter in case of failure. It will be
- * decremented on success.
- */
- psBase->ui32BatchHandAllocFailures++;
- }
-
- /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
- {
- /* See if there is already a handle for this data pointer */
- hHandle = FindHandle(psBase, pvData, eType, IMG_NULL);
-#if defined (SUPPORT_SID_INTERFACE)
- if (hHandle != 0)
-#else
- if (hHandle != IMG_NULL)
-#endif
- {
- struct sHandle *psHandle;
-
- eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed"));
- return eError;
- }
-
- /*
- * If the client is willing to share a handle, and the
- * existing handle is marked as shareable, return the
- * existing handle.
- */
- if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
- {
- *phHandle = hHandle;
- eError = PVRSRV_OK;
- goto exit_ok;
- }
-
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
- }
- }
-
- eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL);
-
-exit_ok:
- if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK))
- {
- psBase->ui32BatchHandAllocFailures--;
- }
-
- return eError;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVAllocSubHandle
-
- @Description Allocate a subhandle
-
- @Input phHandle - location for new subhandle
- pvData - pointer to resource to be associated with the subhandle
- eType - the type of resource
- hParent - parent handle
-
- @Output phHandle - points to new subhandle
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent)
-#else
-PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent)
-#endif
-{
- struct sHandle *psPHand;
- struct sHandle *psCHand;
- PVRSRV_ERROR eError;
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hParentKey;
- IMG_SID hHandle;
-
- *phHandle = 0;
-#else
- IMG_HANDLE hParentKey;
- IMG_HANDLE hHandle;
-
- *phHandle = IMG_NULL;
-#endif
-
- if (HANDLES_BATCHED(psBase))
- {
- /*
- * Increment the counter in case of failure. It will be
- * decremented on success.
- */
- psBase->ui32BatchHandAllocFailures++;
- }
-
- /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
- hParent : IMG_NULL;
-
- /* Lookup the parent handle */
- eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE);
- if (eError != PVRSRV_OK)
- {
- return eError;
- }
-
- if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
- {
- /* See if there is already a handle for this data pointer */
- hHandle = FindHandle(psBase, pvData, eType, hParentKey);
-#if defined (SUPPORT_SID_INTERFACE)
- if (hHandle != 0)
-#else
- if (hHandle != IMG_NULL)
-#endif
- {
- struct sHandle *psCHandle;
- PVRSRV_ERROR eErr;
-
- eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType);
- if (eErr != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
- return eErr;
- }
-
- PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent);
-
- /*
- * If the client is willing to share a handle, the
- * existing handle is marked as shareable, and the
- * existing handle has the same parent, return the
- * existing handle.
- */
- if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent)
- {
- *phHandle = hHandle;
- goto exit_ok;
- }
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
- }
- }
-
- eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey);
- if (eError != PVRSRV_OK)
- {
- return eError;
- }
-
- /*
- * Get the parent handle structure again, in case the handle
- * structure has moved (depending on the implementation
- * of AllocHandle).
- */
- psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent);
-
- psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle);
-
- AdoptChild(psBase, psPHand, psCHand);
-
- *phHandle = hHandle;
-
-exit_ok:
- if (HANDLES_BATCHED(psBase))
- {
- psBase->ui32BatchHandAllocFailures--;
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVFindHandle
-
- @Description Find handle corresponding to a resource pointer
-
- @Input phHandle - location for returned handle
- pvData - pointer to resource to be associated with the handle
- eType - the type of resource
-
- @Output phHandle - points to handle
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
-#else
-PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType)
-#endif
-{
-#if defined (SUPPORT_SID_INTERFACE)
- IMG_SID hHandle;
-#else
- IMG_HANDLE hHandle;
-#endif
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- /* See if there is a handle for this data pointer */
-#if defined (SUPPORT_SID_INTERFACE)
- hHandle = (IMG_SID) FindHandle(psBase, pvData, eType, IMG_NULL);
-#else
- hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL);
-#endif
- if (hHandle == IMG_NULL)
- {
- return PVRSRV_ERROR_HANDLE_NOT_FOUND;
- }
-
- *phHandle = hHandle;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVLookupHandleAnyType
-
- @Description Lookup the data pointer and type corresponding to a handle
-
- @Input ppvData - location to return data pointer
- peType - location to return handle type
- hHandle - handle from client
-
- @Output ppvData - points to the data pointer
- peType - points to handle type
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle)
-#else
-PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle)
-#endif
-{
- struct sHandle *psHandle;
- PVRSRV_ERROR eError;
-
- eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError));
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return eError;
- }
-
- *ppvData = psHandle->pvData;
- *peType = psHandle->eType;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVLookupHandle
-
- @Description Lookup the data pointer corresponding to a handle
-
- @Input ppvData - location to return data pointer
- hHandle - handle from client
- eType - handle type
-
- @Output ppvData - points to the data pointer
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
-#else
-PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
-#endif
-{
- struct sHandle *psHandle;
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_ASSERT(hHandle != 0);
-#endif
-
- eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError));
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return eError;
- }
-
- *ppvData = psHandle->pvData;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVLookupSubHandle
-
- @Description Lookup the data pointer corresponding to a subhandle
-
- @Input ppvData - location to return data pointer
- hHandle - handle from client
- eType - handle type
- hAncestor - ancestor handle
-
- @Output ppvData - points to the data pointer
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor)
-#else
-PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor)
-#endif
-{
- struct sHandle *psPHand;
- struct sHandle *psCHand;
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_ASSERT(hHandle != 0);
-#endif
-
- eError = GetHandleStructure(psBase, &psCHand, hHandle, eType);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError));
- return eError;
- }
-
- /* Look for hAncestor among the handle's ancestors */
- for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; )
- {
- eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor"));
- return PVRSRV_ERROR_INVALID_SUBHANDLE;
- }
- }
-
- *ppvData = psCHand->pvData;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVGetParentHandle
-
- @Description Lookup the parent of a handle
-
- @Input phParent - location for returning parent handle
- hHandle - handle for which the parent handle is required
- eType - handle type
- hParent - parent handle
-
- @Output *phParent - parent handle, or IMG_NULL if there is no parent
-
- @Return Error code or PVRSRV_OK. Note that not having a parent is
- not regarded as an error.
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
-#else
-PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
-#endif
-{
- struct sHandle *psHandle;
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError));
- return eError;
- }
-
- *phParent = ParentHandle(psHandle);
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVLookupAndReleaseHandle
-
- @Description Lookup the data pointer corresponding to a handle
-
- @Input ppvData - location to return data pointer
- hHandle - handle from client
- eType - handle type
- eFlag - lookup flags
-
- @Output ppvData - points to the data pointer
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
-#else
-PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
-#endif
-{
- struct sHandle *psHandle;
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError));
-#if defined (SUPPORT_SID_INTERFACE)
- PVR_DBG_BREAK
-#endif
- return eError;
- }
-
- *ppvData = psHandle->pvData;
-
- eError = FreeHandle(psBase, psHandle);
-
- return eError;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVReleaseHandle
-
- @Description Release a handle that is no longer needed
-
- @Input hHandle - handle from client
- eType - handle type
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-#if defined (SUPPORT_SID_INTERFACE)
-PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType)
-#else
-PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType)
-#endif
-{
- struct sHandle *psHandle;
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
-
- eError = GetHandleStructure(psBase, &psHandle, hHandle, eType);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError));
- return eError;
- }
-
- eError = FreeHandle(psBase, psHandle);
-
- return eError;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVNewHandleBatch
-
- @Description Start a new handle batch
-
- @Input psBase - handle base
- @Input ui32BatchSize - handle batch size
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize)
-{
- PVRSRV_ERROR eError;
-
- if (HANDLES_BATCHED(psBase))
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize));
- return PVRSRV_ERROR_HANDLE_BATCH_IN_USE;
- }
-
- if (ui32BatchSize == 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- eError = EnsureFreeHandles(psBase, ui32BatchSize);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError));
- return eError;
- }
-
- psBase->ui32HandBatchSize = ui32BatchSize;
-
- /* Record current number of handles */
- psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount;
-
- PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0);
-
- PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0);
-
- PVR_ASSERT(HANDLES_BATCHED(psBase));
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVHandleBatchCommitOrRelease
-
- @Description Release a handle batch
-
- @Input psBase - handle base
- bCommit - commit handles
-
- @Return none
-
-******************************************************************************/
-static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit)
-{
-
- IMG_UINT32 ui32IndexPlusOne;
- IMG_BOOL bCommitBatch = bCommit;
-
- if (!HANDLES_BATCHED(psBase))
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch"));
- return PVRSRV_ERROR_INVALID_PARAMS;
-
- }
-
- if (psBase->ui32BatchHandAllocFailures != 0)
- {
- if (bCommit)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures."));
- }
- bCommitBatch = IMG_FALSE;
- }
- /*
- * The whole point of batched handles is to avoid handle allocation
- * failures.
- */
- PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit);
-
- ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne;
- while(ui32IndexPlusOne != 0)
- {
- struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32IndexPlusOne - 1);
- IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne;
- PVR_ASSERT(BATCHED_HANDLE(psHandle));
-
- psHandle->ui32NextIndexPlusOne = 0;
-
- if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
- {
- PVRSRV_ERROR eError;
-
- /*
- * We need a complete free here. If the handle
- * is not partially free, set the handle as
- * unbatched to avoid a partial free.
- */
- if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle))
- {
- /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */
- SET_UNBATCHED_HANDLE(psHandle); /* PRQA S 4130 */ /* mis-use of enums FIXME*/
- }
-
- eError = FreeHandle(psBase, psHandle);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError));
- }
- PVR_ASSERT(eError == PVRSRV_OK);
- }
- else
- {
- /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */
- SET_UNBATCHED_HANDLE(psHandle);
- }
-
- ui32IndexPlusOne = ui32NextIndexPlusOne;
- }
-
-#ifdef DEBUG
- if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount)
- {
- IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch;
-
- PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch);
-
- PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small. Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize, psBase->ui32HandBatchSize + ui32Delta));
-
- }
-#endif
-
- psBase->ui32HandBatchSize = 0;
- psBase->ui32FirstBatchIndexPlusOne = 0;
- psBase->ui32TotalHandCountPreBatch = 0;
- psBase->ui32BatchHandAllocFailures = 0;
-
- if (psBase->ui32BatchHandAllocFailures != 0 && bCommit)
- {
- PVR_ASSERT(!bCommitBatch);
-
- return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE;
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVCommitHandleBatch
-
- @Description Commit a handle batch
-
- @Input psBase - handle base
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase)
-{
- return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE);
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRReleaseHandleBatch
-
- @Description Release a handle batch
-
- @Input psBase - handle base
-
- @Return none
-
-******************************************************************************/
-IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase)
-{
- (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE);
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVSetMaxHandle
-
- @Description Set maximum handle number for given handle base
-
- @Input psBase - pointer to handle base structure
- ui32MaxHandle - Maximum handle number
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle)
-{
- IMG_UINT32 ui32MaxHandleRounded;
-
- if (HANDLES_BATCHED(psBase))
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- /* Validate the limit */
- if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE));
-
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- /* The limit can only be set if no handles have been allocated */
- if (psBase->ui32TotalHandCount != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated"));
-
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle);
-
- /*
- * Allow the maximum number of handles to be reduced, but never to
- * zero.
- */
- if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne)
- {
- psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded;
- }
-
- PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0);
- PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE);
- PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0);
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVGetMaxHandle
-
- @Description Get maximum handle number for given handle base
-
- @Input psBase - pointer to handle base structure
-
- @Output Maximum handle number, or 0 if handle limits not
- supported.
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase)
-{
- return psBase->ui32MaxIndexPlusOne;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVEnableHandlePurging
-
- @Description Enable purging for a given handle base
-
- @Input psBase - pointer to handle base structure
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase)
-{
- if (psBase->bPurgingEnabled)
- {
- PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled"));
- return PVRSRV_OK;
- }
-
- /* Purging can only be enabled if no handles have been allocated */
- if (psBase->ui32TotalHandCount != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- psBase->bPurgingEnabled = IMG_TRUE;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVPurgeHandles
-
- @Description Purge handles for a given handle base
-
- @Input psBase - pointer to handle base structure
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
-{
- IMG_UINT32 ui32BlockIndex;
- IMG_UINT32 ui32NewHandCount;
-
- if (!psBase->bPurgingEnabled)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base"));
- return PVRSRV_ERROR_NOT_SUPPORTED;
- }
-
- if (HANDLES_BATCHED(psBase))
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0);
-
- for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--)
- {
- if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE)
- {
- break;
- }
- }
- ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex);
-
- /*
- * Check for a suitable decrease in the handle count.
- */
- if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2))
- {
- PVRSRV_ERROR eError;
-
- // PVR_TRACE((" PVRSRVPurgeHandles: reducing number of handles from %u to %u", psBase->ui32TotalHandCount, ui32NewHandCount));
-
- eError = ReallocHandleArray(psBase, ui32NewHandCount);
- if (eError != PVRSRV_OK)
- {
- return eError;
- }
- }
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVAllocHandleBase
-
- @Description Allocate a handle base structure for a process
-
- @Input ppsBase - pointer to handle base structure pointer
-
- @Output ppsBase - points to handle base structure pointer
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
-{
- PVRSRV_HANDLE_BASE *psBase;
- IMG_HANDLE hBlockAlloc;
- PVRSRV_ERROR eError;
-
- eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
- sizeof(*psBase),
- (IMG_PVOID *)&psBase,
- &hBlockAlloc,
- "Handle Base");
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError));
- return eError;
- }
- OSMemSet(psBase, 0, sizeof(*psBase));
-
- /* Create hash table */
- psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default);
- if (psBase->psHashTab == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n"));
- (IMG_VOID)PVRSRVFreeHandleBase(psBase);
- return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
- }
-
- psBase->hBaseBlockAlloc = hBlockAlloc;
-
- psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE;
-
- *ppsBase = psBase;
-
- return PVRSRV_OK;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVFreeHandleBase
-
- @Description Free a handle base structure
-
- @Input psBase - pointer to handle base structure
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase)
-{
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(psBase != gpsKernelHandleBase);
-
- eError = FreeHandleBase(psBase);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError));
- }
-
- return eError;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVHandleInit
-
- @Description Initialise handle management
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID)
-{
- PVRSRV_ERROR eError;
-
- PVR_ASSERT(gpsKernelHandleBase == IMG_NULL);
-
- eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError));
- goto error;
- }
-
- eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError));
- goto error;
- }
-
- return PVRSRV_OK;
-error:
- (IMG_VOID) PVRSRVHandleDeInit();
- return eError;
-}
-
-/*!
-******************************************************************************
-
- @Function PVRSRVHandleDeInit
-
- @Description De-initialise handle management
-
- @Return Error code or PVRSRV_OK
-
-******************************************************************************/
-PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID)
-{
- PVRSRV_ERROR eError = PVRSRV_OK;
-
- if (gpsKernelHandleBase != IMG_NULL)
- {
- eError = FreeHandleBase(gpsKernelHandleBase);
- if (eError == PVRSRV_OK)
- {
- gpsKernelHandleBase = IMG_NULL;
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError));
- }
- }
-
- return eError;
-}
-#else
-/* disable warning about empty module */
-#endif /* #if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) */
-/******************************************************************************
- End of file (handle.c)
-******************************************************************************/