/****************************************************************************
*
*    Copyright (c) 2005 - 2011 by Vivante Corp.  All rights reserved.
*
*    The material in this file is confidential and contains trade secrets
*    of Vivante Corporation. This is proprietary information owned by
*    Vivante Corporation. No part of this work may be disclosed,
*    reproduced, copied, transmitted, or used in any way for any purpose,
*    without the express written permission of Vivante Corporation.
*
*****************************************************************************
*
*    Auto-generated file on 11/29/2011. Do not edit!!!
*
*****************************************************************************/




/*
**	Include file for the local memory management.
*/

#ifndef __gc_hal_mem_h_
#define __gc_hal_mem_h_
#ifndef VIVANTE_NO_3D

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
**  Usage:

	The macros to declare MemPool type and functions are
	gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
	gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
	gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)

	The data structures for MemPool are
	typedef struct _gcsMEM_FS_MEM_POOL *	gcsMEM_FS_MEM_POOL;
	typedef struct _gcsMEM_VS_MEM_POOL *	gcsMEM_VS_MEM_POOL;
	typedef struct _gcsMEM_AFS_MEM_POOL *	gcsMEM_AFS_MEM_POOL;

	The MemPool constructor and destructor functions are
	gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
	gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
	gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
	gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
	gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
	gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);

	FS:  for Fixed-Size data structures
	VS:  for Variable-size data structures
	AFS: for Array of Fixed-Size data structures


	// Example 1: For a fixed-size data structure, struct gcsNode.
	// It is used locally in a file, so the functions are static without prefix.
	// At top level, declear allocate and free functions.
	// The first argument is the data type.
	// The second armument is the short name used in the fuctions.
	gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );

	// The previous macro creates two inline functions,
	// _AllocateNode and _FreeNode.

	// In function or struct
	gcsMEM_FS_MEM_POOL nodeMemPool;

	// In function,
	struct gcsNode * node;
	gceSTATUS status;

	// Before using the memory pool, initialize it.
	// The second argument is the gcoOS object.
	// The third argument is the number of data structures to allocate for each chunk.
	status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
	...

	// Allocate a node.
	status = _AllocateNode(nodeMemPool, &node);
	...
	// Free a node.
	_FreeNode(nodeMemPool, node);

	// After using the memory pool, free it.
	gcfMEM_FreeFSMemPool(&nodeMemPool);


	// Example 2: For array of fixed-size data structures, struct gcsNode.
	// It is used in several files, so the functions are extern with prefix.
	// At top level, declear allocate and free functions.
	// The first argument is the data type, and the second one is the short name
	// used in the fuctions.
	gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);

	// The previous macro creates two inline functions,
	// gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.

	// In function or struct
	gcsMEM_AFS_MEM_POOL nodeArrayMemPool;

	// In function,
	struct gcsNode * nodeArray;
	gceSTATUS status;

	// Before using the array memory pool, initialize it.
	// The second argument is the gcoOS object, the third is the number of data
	// structures to allocate for each chunk.
	status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
	...

	// Allocate a node array of size 100.
	status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
	...
	// Free a node array.
	gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);

	// After using the array memory pool, free it.
	gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);

*******************************************************************************/

/*******************************************************************************
**	To switch back to use gcoOS_Allocate and gcoOS_Free, add
**	#define USE_LOCAL_MEMORY_POOL 0
**	before including this file.
*******************************************************************************/
#ifndef USE_LOCAL_MEMORY_POOL
/*
    USE_LOCAL_MEMORY_POOL

    This define enables the local memory management to improve performance.
*/
#define USE_LOCAL_MEMORY_POOL		1
#endif

/*******************************************************************************
**							Memory Pool Data Structures
*******************************************************************************/
#if USE_LOCAL_MEMORY_POOL
	typedef struct _gcsMEM_FS_MEM_POOL *	gcsMEM_FS_MEM_POOL;
	typedef struct _gcsMEM_VS_MEM_POOL *	gcsMEM_VS_MEM_POOL;
	typedef struct _gcsMEM_AFS_MEM_POOL *	gcsMEM_AFS_MEM_POOL;
#else
	typedef gcoOS	gcsMEM_FS_MEM_POOL;
	typedef gcoOS	gcsMEM_VS_MEM_POOL;
	typedef gcoOS	gcsMEM_AFS_MEM_POOL;
#endif

/*******************************************************************************
**							Memory Pool Macros
*******************************************************************************/
#if USE_LOCAL_MEMORY_POOL
#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type **					Pointer \
	) \
{ \
	return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
} \
 \
gceSTATUS \
Prefix##_CAllocate##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type **					Pointer \
	) \
{ \
	gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
	gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
	gcmVERIFY_OK(gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type))); \
    gcmFOOTER(); \
	return gcvSTATUS_OK; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type *					Pointer \
	) \
{ \
    gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
    status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
    gcmFOOTER(); \
	return status; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName##List( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type *					FirstPointer, \
	Type *					LastPointer \
	) \
{ \
    gceSTATUS               status; \
    gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \
    status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \
    gcmFOOTER(); \
	return status; \
}

#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Size \
	) \
{ \
    gceSTATUS               status;\
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
    status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \
    gcmFOOTER(); \
	return status; \
} \
 \
gceSTATUS \
 Prefix##_CAllocate##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Size \
	) \
{ \
	gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
	gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
	gcmVERIFY_OK(gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size)); \
    gcmFOOTER(); \
	return gcvSTATUS_OK; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type *					Pointer \
	) \
{ \
    gceSTATUS               status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \
    status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
    gcmFOOTER(); \
	return status; \
}

#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
	gcsMEM_AFS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Count \
	) \
{ \
    gceSTATUS               status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
    status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \
    gcmFOOTER(); \
	return status; \
} \
 \
gceSTATUS \
Prefix##_CAllocate##TypeName( \
	gcsMEM_AFS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Count \
	) \
{ \
	gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
	gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
	gcmVERIFY_OK(gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type))); \
    gcmFOOTER(); \
	return gcvSTATUS_OK; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName( \
	gcsMEM_AFS_MEM_POOL		MemPool, \
	Type *					Pointer \
	) \
{ \
    gceSTATUS               status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
    status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
    gcmFOOTER(); \
	return status; \
}

#else

#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type **					Pointer \
	) \
{ \
    gceSTATUS               status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
    status = gcoOS_Allocate(MemPool, \
							gcmSIZEOF(Type), \
							(gctPOINTER *) Pointer); \
    gcmFOOTER(); \
	return status; \
} \
 \
gceSTATUS \
Prefix##_CAllocate##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type **					Pointer \
	) \
{ \
	gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
	gcmERR_RETURN(gcoOS_Allocate(MemPool, \
							gcmSIZEOF(Type), \
							(gctPOINTER *) Pointer)); \
	gcmVERIFY_OK(gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type))); \
    gcmFOOTER(); \
	return gcvSTATUS_OK; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName( \
	gcsMEM_FS_MEM_POOL		MemPool, \
	Type *					Pointer \
	) \
{ \
    gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
    status = gcmOS_SAFE_FREE(MemPool, Pointer); \
    gcmFOOTER(); \
	return status; \
}

#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
	gcsMEM_VS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Size \
	) \
{ \
    gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
    status = gcoOS_Allocate(MemPool, \
							Size, \
							(gctPOINTER *) Pointer); \
    gcmFOOTER(); \
	return status; \
} \
 \
gceSTATUS \
Prefix##_CAllocate##TypeName( \
	gcsMEM_VS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Size \
	) \
{ \
	gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
	gcmERR_RETURN(gcoOS_Allocate(MemPool, \
							Size, \
							(gctPOINTER *) Pointer)); \
	gcmVERIFY_OK(gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size)); \
    gcmFOOTER(); \
	return gcvSTATUS_OK; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName( \
	gcsMEM_VS_MEM_POOL		MemPool, \
	Type *					Pointer \
	) \
{ \
    gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
    status = gcmOS_SAFE_FREE(MemPool, Pointer); \
    gcmFOOTER(); \
	return status; \
}

#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
gceSTATUS \
Prefix##_Allocate##TypeName( \
	gcsMEM_AFS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Count \
	) \
{ \
    gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
    status = gcoOS_Allocate(MemPool, \
							Count * gcmSIZEOF(Type), \
							(gctPOINTER *) Pointer); \
    gcmFOOTER(); \
	return status; \
} \
 \
gceSTATUS \
Prefix##_CAllocate##TypeName( \
	gcsMEM_AFS_MEM_POOL		MemPool, \
	Type **					Pointer, \
	gctUINT					Count \
	) \
{ \
	gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
	gcmERR_RETURN(gcoOS_Allocate(MemPool, \
							Count * gcmSIZEOF(Type), \
							(gctPOINTER *) Pointer)); \
	gcmVERIFY_OK(gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type))); \
    gcmFOOTER(); \
	return gcvSTATUS_OK; \
} \
 \
gceSTATUS \
Prefix##_Free##TypeName( \
	gcsMEM_AFS_MEM_POOL		MemPool, \
	Type *					Pointer \
	) \
{ \
    gceSTATUS				status; \
    gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
    status = gcmOS_SAFE_FREE(MemPool, Pointer); \
    gcmFOOTER(); \
	return status; \
}
#endif

/*******************************************************************************
**							Memory Pool Data Functions
*******************************************************************************/
gceSTATUS
gcfMEM_InitFSMemPool(
	IN gcsMEM_FS_MEM_POOL * MemPool,
	IN gcoOS				OS,
	IN gctUINT				NodeCount,
	IN gctUINT				NodeSize
	);

gceSTATUS
gcfMEM_FreeFSMemPool(
	IN gcsMEM_FS_MEM_POOL * MemPool
	);

gceSTATUS
gcfMEM_FSMemPoolGetANode(
	IN gcsMEM_FS_MEM_POOL	MemPool,
	OUT gctPOINTER *		Node
	);

gceSTATUS
gcfMEM_FSMemPoolFreeANode(
	IN gcsMEM_FS_MEM_POOL	MemPool,
	IN gctPOINTER			Node
	);

gceSTATUS
gcfMEM_FSMemPoolFreeAList(
	IN gcsMEM_FS_MEM_POOL	MemPool,
	IN gctPOINTER			FirstNode,
	IN gctPOINTER			LastNode
	);

gceSTATUS
gcfMEM_InitVSMemPool(
	IN gcsMEM_VS_MEM_POOL * MemPool,
	IN gcoOS				OS,
	IN gctUINT				BlockSize,
	IN gctBOOL				RecycleFreeNode
	);

gceSTATUS
gcfMEM_FreeVSMemPool(
	IN gcsMEM_VS_MEM_POOL * MemPool
	);

gceSTATUS
gcfMEM_VSMemPoolGetANode(
	IN gcsMEM_VS_MEM_POOL	MemPool,
	IN gctUINT				Size,
	IN gctUINT				Alignment,
	OUT gctPOINTER *		Node
	);

gceSTATUS
gcfMEM_VSMemPoolFreeANode(
	IN gcsMEM_VS_MEM_POOL	MemPool,
	IN gctPOINTER			Node
	);

gceSTATUS
gcfMEM_InitAFSMemPool(
	IN gcsMEM_AFS_MEM_POOL *MemPool,
	IN gcoOS				OS,
	IN gctUINT				NodeCount,
	IN gctUINT				NodeSize
	);

gceSTATUS
gcfMEM_FreeAFSMemPool(
	IN gcsMEM_AFS_MEM_POOL *MemPool
	);

gceSTATUS
gcfMEM_AFSMemPoolGetANode(
	IN gcsMEM_AFS_MEM_POOL	MemPool,
	IN gctUINT				Count,
	OUT gctPOINTER *		Node
	);

gceSTATUS
gcfMEM_AFSMemPoolFreeANode(
	IN gcsMEM_AFS_MEM_POOL	MemPool,
	IN gctPOINTER			Node
	);

#ifdef __cplusplus
}
#endif

#endif /* VIVANTE_NO_3D */
#endif /* __gc_hal_mem_h_ */
