/*H********************************************************************************/ /*! \File dirtymem.c \Description DirtySock memory allocation routines. \Copyright Copyright (c) 2005 Electronic Arts Inc. \Version 10/12/2005 (jbrookes) First Version \Version 11/19/2008 (mclouatre) Adding pMemGroupUserData to mem groups */ /********************************************************************************H*/ /*** Include files ****************************************************************/ #include #include "DirtySDK/dirtysock.h" #include "DirtySDK/dirtysock/dirtymem.h" /*** Defines **********************************************************************/ #define DIRTYMEM_MAXGROUPS (16) /*** Type Definitions *************************************************************/ typedef struct DirtyMemInfoT { int32_t iMemGroup; void *pMemGroupUserData; } DirtyMemInfoT; /*** Variables ********************************************************************/ static int32_t _DirtyMem_iGroup = 0; static DirtyMemInfoT _DirtyMem_iGroupStack[DIRTYMEM_MAXGROUPS] = { {'dflt', NULL} }; //#if defined(DIRTYCODE_DLL) static DirtyMemFreeT *_DirtyMem_pMemFreeFunc = NULL; static DirtyMemAllocT *_DirtyMem_pMemAllocFunc = NULL; //#endif /*** Private Functions ************************************************************/ /*** Public functions *************************************************************/ /*F********************************************************************************/ /*! \Function DirtyMemGroupEnter \Description Set group that will be used for allocations. \Input iMemGroup - group id \Input *pMemGroupUserData - User-provided data pointer \Output None. \Version 10/13/2005 (jbrookes) \Version 11/19/2008 (mclouatre) Adding pMemGroupUserData to mem groups */ /********************************************************************************F*/ void DirtyMemGroupEnter(int32_t iMemGroup, void *pMemGroupUserData) { // DIRTYMEM_MAXGROUPS - 1: the first slot is occupied by 'dflt' if (_DirtyMem_iGroup >= (DIRTYMEM_MAXGROUPS - 1)) { NetPrintf(("dirtymem: group stack overflow\n")); return; } _DirtyMem_iGroup += 1; _DirtyMem_iGroupStack[_DirtyMem_iGroup].iMemGroup = iMemGroup; _DirtyMem_iGroupStack[_DirtyMem_iGroup].pMemGroupUserData = pMemGroupUserData; } /*F********************************************************************************/ /*! \Function DirtyMemGroupLeave \Description Restore previous group that will be used for allocations. \Version 10/13/2005 (jbrookes) */ /********************************************************************************F*/ void DirtyMemGroupLeave(void) { if (_DirtyMem_iGroup <= 0) { NetPrintf(("dirtymem: group stack underflow\n")); return; } _DirtyMem_iGroup -= 1; } /*F********************************************************************************/ /*! \Function DirtyMemGroupQuery \Description Return current memory group data. \Input *pMemGroup - [OUT param] pointer to variable to be filled with mem group id \Input **ppMemGroupUserData - [OUT param] pointer to variable to be filled with pointer to user data \Output None. \Version 10/13/2005 (jbrookes) \Version 11/18/2008 (mclouatre) returned values now passed in [OUT] parameters */ /********************************************************************************F*/ void DirtyMemGroupQuery(int32_t *pMemGroup, void **ppMemGroupUserData) { if (pMemGroup != NULL) { *pMemGroup = _DirtyMem_iGroupStack[_DirtyMem_iGroup].iMemGroup; } if (ppMemGroupUserData != NULL) { *ppMemGroupUserData = _DirtyMem_iGroupStack[_DirtyMem_iGroup].pMemGroupUserData; } } /*F********************************************************************************/ /*! \Function DirtyMemDebugAlloc \Description Display memory allocation information to debug output. \Input *pMem - address of memory being freed \Input iSize - size of allocation \Input iMemModule - memory module \Input iMemGroup - memory group \Input *pMemGroupUserData - pointer to user data \Output None. \Version 10/13/2005 (jbrookes) \Version 11/18/2008 (mclouatre) adding pMemGroupUserData parameter */ /********************************************************************************F*/ #if DIRTYCODE_DEBUG void DirtyMemDebugAlloc(void *pMem, int32_t iSize, int32_t iMemModule, int32_t iMemGroup, void *pMemGroupUserData) { NetPrintf(("dirtymem: [a] %p mod=%C grp=%C udataptr=%p size=%d\n", pMem, iMemModule, iMemGroup, pMemGroupUserData, iSize)); } #endif /*F********************************************************************************/ /*! \Function DirtyMemDebugFree \Description Display memory free information to debug output. \Input *pMem - address of memory being freed \Input iSize - size of allocation (if available), or zero \Input iMemModule - memory module \Input iMemGroup - memory group \Input *pMemGroupUserData - pointer to user data \Output None. \Version 10/13/2005 (jbrookes) \Version 11/18/2008 (mclouatre) adding pMemGroupUserData parameter */ /********************************************************************************F*/ #if DIRTYCODE_DEBUG void DirtyMemDebugFree(void *pMem, int32_t iSize, int32_t iMemModule, int32_t iMemGroup, void *pMemGroupUserData) { NetPrintf(("dirtymem: [f] %p mod=%C grp=%C udataptr=%p size=%d\n", pMem, iMemModule, iMemGroup, pMemGroupUserData, iSize)); } #endif //#if defined(DIRTYCODE_DLL) /*F********************************************************************************/ /*! \Function DirtyMemFuncSet \Description This is only avaliable in the DLL mode. Set Memory Allocate and Free functions that DirtySDK will use. If any of the parameters are NULL it will use the default implementation \Input *pMemAlloc - function pointer to Mem Alloc function \Input *pMemFree - function pointer to Mem Free function \Output None. \Version 3/14/2014 (tcho) */ /********************************************************************************F*/ void DirtyMemFuncSet(DirtyMemAllocT *pMemAlloc, DirtyMemFreeT *pMemFree) { _DirtyMem_pMemFreeFunc = pMemFree; _DirtyMem_pMemAllocFunc = pMemAlloc; } /*F********************************************************************************/ /*! \Function DirtyMemAlloc \Description Only Avaliable in DLL mode. Implementation of the required DirtySock memory allocation routine. \Input iSize - size of memory to allocate \Input iMemModule - memory module id \Input iMemGroup - memory group id \Input *pMemGroupUserData - user data associated with mem group \Output void * - pointer to newly allocated memory, or NULL \Version 3/14/2014 (tcho) */ /********************************************************************************F*/ void *DirtyMemAlloc(int32_t iSize, int32_t iMemModule, int32_t iMemGroup, void * pMemGroupUserData) { void *pMem = NULL; if (_DirtyMem_pMemAllocFunc != NULL) { pMem = _DirtyMem_pMemAllocFunc(iSize, iMemModule, iMemGroup, pMemGroupUserData); } else { pMem = (void *)malloc(iSize); } return(pMem); } /*F********************************************************************************/ /*! \Function DirtyMemFree \Description Only Avaliable in DLL mode. Implementation of the required DirtySock memory free routine. \Input *pMem - pointer to memory block to free \Input iMemModule - memory module id \Input iMemGroup - memory group id \Input *pMemGroupUserData - user data associated with mem group \Output None. \Version 3/14/2014 (tcho) */ /********************************************************************************F*/ void DirtyMemFree(void *pMem, int32_t iMemModule, int32_t iMemGroup, void *pMemGroupUserData) { if (_DirtyMem_pMemFreeFunc != NULL) { _DirtyMem_pMemFreeFunc(pMem, iMemModule, iMemGroup, pMemGroupUserData); } else { free(pMem); } } //#endif