Example #1
0
MF_API MFVertexBuffer *MFVertex_CreateVertexBuffer(const MFVertexDeclaration *pVertexFormat, int numVerts, MFVertexBufferType type, void *pVertexBufferMemory, const char *pName)
{
	int nameLen = pName ? MFString_Length(pName) + 1 : 0;
	MFVertexBuffer *pVB;
	if(type == MFVBType_Scratch)
		pVB = (MFVertexBuffer*)MFRenderer_AllocateScratchMemory(sizeof(MFVertexBuffer) + nameLen);
	else
		pVB = (MFVertexBuffer*)MFHeap_Alloc(sizeof(MFVertexBuffer) + nameLen);
	MFZeroMemory(pVB, sizeof(MFVertexBuffer));

	if(pName)
		pName = MFString_Copy((char*)&pVB[1], pName);

	pVB->pVertexDeclatation = pVertexFormat;
	pVB->bufferType = type;
	pVB->numVerts = numVerts;

	if(!MFVertex_CreateVertexBufferPlatformSpecific(pVB, pVertexBufferMemory))
	{
		if(type != MFVBType_Scratch)
			MFHeap_Free(pVB);
		return NULL;
	}

	if(type == MFVBType_Scratch)
	{
		// add to a scratch list that will be cleaned up later...
		pVB->pNextScratchBuffer = gpScratchBufferList;
		gpScratchBufferList = pVB;
	}
	else
		MFResource_AddResource(pVB, MFRT_VertexBuffer, (uint32)(MFUtil_HashPointer(pVB) & 0xFFFFFFFF), pName);

	return pVB;
}
Example #2
0
static MFAllocHeader *GetAllocHeader(const void *pMemory)
{
	int hash = MFUtil_HashPointer(pMemory) % MFHeap_AllocTableLength;

	MFHeap_AllocItem *pI = gpAllocTable[hash];
	while(pI && pI->pMemory != pMemory)
		pI = pI->pNext;
	if(!pI)
		return NULL;
	return &pI->header;
}
Example #3
0
static MFAllocHeader *AddAlloc(void *pMemory, size_t bytes, const char *pDesc)
{
	if(numFree == 0)
		ExpandAllocTable();

	MFHeap_AllocItem *pAlloc = gppFreeList[--numFree];
	pAlloc->pMemory = pMemory;

	int hash = MFUtil_HashPointer(pMemory) % MFHeap_AllocTableLength;
	pAlloc->pNext = gpAllocTable[hash];
	gpAllocTable[hash] = pAlloc;

	return &pAlloc->header;
}
Example #4
0
MFInitStatus MFHeap_InitModule()
{
	MFCALLSTACK;

	MFDebug_Assert(MFThread_GetMutexSizePlatformSpecific() <= sizeof(gMutexBuffer), "Mutex buffer too small!");
	MFThread_InitMutexPlatformSpecific((MFMutex)gMutexBuffer, "MFHeap alloc mutex");
	gAllocMutex = (MFMutex)gMutexBuffer;

	// any heap tracking allocations should be made in the debug space
	MFHeap *pOld = MFHeap_SetActiveHeap(MFHeap_GetDebugHeap());

#if defined(_USE_TRACKING_HASH_TABLE)
	// set up the memory tracking hash table
	// note: this is slightly complicated due to the chicken and egg nature
	// of making the first allocation for the pool its self ;)
	static const int numAllocHeaders = 1024;
//	uint32 bytes = (sizeof(MFHeap_AllocItem) + sizeof(void**)) * numAllocHeaders;
//	void *pPoolMemory = MFHeap_Alloc(bytes);
//	gAllocHeaderPool.Init(sizeof(MFHeap_AllocItem), numAllocHeaders, 1024, pPoolMemory, bytes);
	gAllocHeaderPool.Init(sizeof(MFHeap_AllocItem), numAllocHeaders, 1024);

	MFZeroMemory(gpAllocTable, sizeof(gpAllocTable));

	// artificially add an entry for the pool its self...
	MFHeap_AllocItem *pHeader = (MFHeap_AllocItem*)gAllocHeaderPool.Alloc();
	pHeader->header.pHeap = &gExternalHeap;
	pHeader->header.size = bytes;
	pHeader->header.pFile = __FILE__;
	pHeader->header.line = (uint16)__LINE__;
	pHeader->header.alignment = 4;
	pHeader->pMemory = pPoolMemory;
	pHeader->pNext = NULL;
	gpAllocTable[MFUtil_HashPointer(pPoolMemory) % MFHeap_AllocTableLength] = pHeader;
#endif
#if defined(_USE_ALLOC_TRACKER)
	gAllocList.Init(sizeof(void*), 1024, 1024);
	gPoolInitialised = true;
#endif

	// restore the active heap
	MFHeap_SetActiveHeap(pOld);

	// init the heap
	MFHeap_InitModulePlatformSpecific();

	return MFAIC_Succeeded;
}
Example #5
0
MF_API MFIndexBuffer *MFVertex_CreateIndexBuffer(int numIndices, uint16 *pIndexBufferMemory, const char *pName)
{
	int nameLen = pName ? MFString_Length(pName) + 1 : 0;
	MFIndexBuffer *pIB = (MFIndexBuffer*)MFHeap_AllocAndZero(sizeof(MFIndexBuffer) + nameLen);

	if(pName)
		pName = MFString_Copy((char*)&pIB[1], pName);

	pIB->numIndices = numIndices;

	if(!MFVertex_CreateIndexBufferPlatformSpecific(pIB, pIndexBufferMemory))
	{
		MFHeap_Free(pIB);
		return NULL;
	}

	MFResource_AddResource(pIB, MFRT_IndexBuffer, (uint32)(MFUtil_HashPointer(pIB) & 0xFFFFFFFF), pName);

	return pIB;
}
Example #6
0
static void FreeAlloc(void *pMemory)
{
	int hash = MFUtil_HashPointer(pMemory) % MFHeap_AllocTableLength;
	MFDebug_Assert(gpAllocTable[hash], "No allocation record! O_O");

	if(gpAllocTable[hash]->pMemory == pMemory)
	{
		gppFreeList[numFree++] = gpAllocTable[hash];
		gpAllocTable[hash] = gpAllocTable[hash]->pNext;
	}
	else
	{
		MFHeap_AllocItem *pI = gpAllocTable[hash];
		while(pI->pNext && pI->pNext->pMemory != pMemory)
			pI = pI->pNext;
		MFDebug_Assert(pI->pNext, "No allocation record! O_O");
		gppFreeList[numFree++] = pI->pNext;
		pI->pNext = pI->pNext->pNext;
	}
}
Example #7
0
MF_API void MFHeap_Free(void *pMem)
{
	MFCALLSTACK;

	if(!pMem)
	{
		MFDebug_Warn(3, "Attemptd to Free 'NULL' pointer.");
		return;
	}

	MFAllocHeader *pHeader = &((MFAllocHeader*)pMem)[-1];
	MFDebug_Assert(MFHeap_ValidateMemory(pMem), MFStr("Memory corruption detected!!\n%s(%d)", pHeader->pFile, pHeader->line));

	MFThread_LockMutex(gAllocMutex);

	MFHeap *pHeap = pHeader->pHeap;
	if(pHeap->heapType != MFHT_Debug)
	{
#if defined(_USE_TRACKING_HASH_TABLE)
		int hash = MFUtil_HashPointer(pMem) % MFHeap_AllocTableLength;
		MFHeap_AllocItem *pT = gpAllocTable[hash];
		if(pT)
		{
			if(pT->pMemory == pMem)
			{
				gpAllocTable[hash] = pT->pNext;
				gAllocHeaderPool.Free(pT);
			}
			else
			{
				while(pT->pNext && pT->pNext->pMemory != pMem)
					pT = pT->pNext;
				if(pT->pNext)
				{
					MFHeap_AllocItem *pTN = pT->pNext;
					pT->pNext = pTN->pNext;
					gAllocHeaderPool.Free(pTN);
				}
			}
		}
#endif
#if defined(_USE_ALLOC_TRACKER)
		if(gPoolInitialised)
		{
			int numAllocs = gAllocList.GetNumAllocated();

			for(int a=0; a<numAllocs; ++a)
			{
				void **ppAlloc = (void**)gAllocList.GetItem(a);
				if(*ppAlloc == pMem)
				{
					gAllocList.Free(ppAlloc);
					break;
				}
			}
		}
#endif
	}

#if !defined(_RETAIL)
	int pad = 0;
	while(pad < (int)sizeof(MFAllocHeader))
		pad += heapAlignment;
	size_t extra = pad + sizeof(MFAllocHeader) + MFHeap_MungwallBytes;

	pHeap->totalAllocated -= pHeader->size + extra;
	pHeap->totalWaste -= extra;
	--pHeap->allocCount;

//	MFDebug_Log(2, MFStr("Free: %08X, %d bytes - %s:(%d)", pMem, pHeader->size, pHeader->pFile, (int)pHeader->line));
#endif

	MFHeap *pAllocHeap = pHeader->pHeap;

	MFCopyMemory((char*)pMem + pHeader->size, "freefreefreefree", MFHeap_MungwallBytes);
	MFCopyMemory((char*)pMem - 8, "freefreefreefree", MFHeap_MungwallBytes);
	MFMemSet(pMem, 0xFE, pHeader->size);

	pAllocHeap->pCallbacks->pFree((char*)pMem - pHeader->alignment, pAllocHeap->pHeapData);

	MFThread_ReleaseMutex(gAllocMutex);
}
Example #8
0
MF_API void *MFHeap_AllocInternal(size_t bytes, MFHeap *pHeap)
{
	MFCALLSTACK;

	MFHeap *pAllocHeap = pOverrideHeap ? pOverrideHeap : (pHeap ? pHeap : pActiveHeap);

	int pad = 0;
	while(pad < (int)sizeof(MFAllocHeader))
		pad += heapAlignment;

	size_t allocExtra = pad + sizeof(MFAllocHeader) + MFHeap_MungwallBytes;
	size_t allocBytes = bytes + allocExtra;

	MFThread_LockMutex(gAllocMutex);

	char *pMemory = (char*)pAllocHeap->pCallbacks->pMalloc(allocBytes, pAllocHeap->pHeapData);

	MFDebug_Assert(pMemory, "Failed to allocate memory!");
	if(pMemory)
	{
		int alignment = (int)(MFALIGN(pMemory + sizeof(MFAllocHeader), heapAlignment) - (uintp)pMemory);

		pMemory += alignment;

		MFAllocHeader *pHeader = &((MFAllocHeader*)pMemory)[-1];

		pHeader->alignment = (uint16)alignment;
		pHeader->pHeap = pAllocHeap;
		pHeader->size = (uint32)bytes;
		pHeader->pFile = gpMFHeap_TrackerFile;
		pHeader->line = (uint16)gMFHeap_TrackerLine;
#if defined(USE_PRE_MUNGWALL)
		MFCopyMemory(pHeader->llawgnum, gLlawgnum, MFHeap_MungwallBytes);
#endif

		if(pAllocHeap->heapType != MFHT_Debug)
		{
#if defined(_USE_TRACKING_HASH_TABLE)
			MFHeap_AllocItem *pAlloc = (MFHeap_AllocItem*)gAllocHeaderPool.Alloc();
			pAlloc->header.alignment = (uint16)alignment;
			pAlloc->header.pHeap = pAllocHeap;
			pAlloc->header.size = (uint32)bytes;
			pAlloc->header.pFile = gpMFHeap_TrackerFile;
			pAlloc->header.line = (uint16)gMFHeap_TrackerLine;
			pAlloc->pMemory = pMemory;

			int hash = MFUtil_HashPointer(pMemory) % MFHeap_AllocTableLength;
			pAlloc->pNext = gpAllocTable[hash];
			gpAllocTable[hash] = pAlloc;
#endif
#if defined(_USE_ALLOC_TRACKER)
			if(gPoolInitialised)
				*(void**)gAllocList.Alloc() = pMemory;
#endif
		}

#if !defined(_RETAIL)
		MFCopyMemory(pMemory + bytes, gMungwall, MFHeap_MungwallBytes);

		pAllocHeap->totalAllocated += allocBytes;
		pAllocHeap->totalWaste += allocExtra;
		++pAllocHeap->allocCount;

//		MFDebug_Log(2, MFStr("Alloc: %08X(%08X), %d bytes - %s:(%d)", pMemory, pMemory - pHeader->alignment, bytes, gpMFHeap_TrackerFile, gMFHeap_TrackerLine));
#endif
	}

	MFThread_ReleaseMutex(gAllocMutex);

	return (void*)pMemory;
}