Example #1
0
MF_API void MFHeap_Free(void *pMem)
{
	MFCALLSTACK;

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

	MFThread_LockMutex(gAllocMutex);

	MFAllocHeader *pHeader = GetAllocHeader(pMem);
	MFDebug_Assert(MFHeap_ValidateMemory(pMem), MFStr("Memory corruption detected!!\n%s(" MFFMT_SIZE_T ")", pHeader->pFile, pHeader->line));

	MFHeap *pHeap = pHeader->pHeap;
#if !defined(_RETAIL)
	size_t extra;
	size_t allocBytes = GetAllocSize(pHeader->size, extra);

	pHeap->totalAllocated -= allocBytes;
	pHeap->totalWaste -= extra;
	--pHeap->allocCount;

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

	MFCopyMemory((char*)pMem + pHeader->size, "freefreefreefree", MFHeap_MungwallBytes);
#if defined(USE_PRE_MUNGWALL)
	MFCopyMemory((char*)pMem - MFHeap_MungwallBytes, "eerfeerfeerfeerf", MFHeap_MungwallBytes);
#endif
	MFMemSet(pMem, 0xFE, pHeader->size);

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

#if defined(_USE_TRACKING_HASH_TABLE)
	FreeAlloc(pMem);
#endif

	MFThread_ReleaseMutex(gAllocMutex);
}
Example #2
0
MF_API bool MFHeap_ValidateHeap()
{
#if defined(_USE_TRACKING_HASH_TABLE)
	MFThread_LockMutex(gAllocMutex);

	for(int i=0; i<MFHeap_AllocTableLength; ++i)
	{
		MFHeap_AllocItem *pI = gpAllocTable[i];
		while(pI)
		{
			if(!MFHeap_ValidateMemory(pI->pMemory))
				MFDebug_Assert(false, "Corrupt memory allocation!");

			pI = pI->pNext;
		}
	}

	MFThread_ReleaseMutex(gAllocMutex);
#endif
	return true;
}
Example #3
0
MF_API bool MFHeap_ValidateHeap()
{
#if defined(_USE_ALLOC_TRACKER)
	MFThread_LockMutex(gAllocMutex);

	if(gPoolInitialised)
	{
		int numAllocated = gAllocList.GetNumAllocated();
		for(int a=0; a<numAllocated; ++a)
		{
			void *pMem = *(void**)gAllocList.GetItem(a);
			if(!MFHeap_ValidateMemory(pMem))
			{
				MFDebug_Assert(false, "Corrupt memory allocation!");
				return false;
			}
		}
	}

	MFThread_ReleaseMutex(gAllocMutex);
#endif
	return true;
}
Example #4
0
MF_API void *MFHeap_ReallocInternal(void *pMem, size_t bytes)
{
	MFCALLSTACK;

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

		void *pNew = MFHeap_AllocInternal(bytes, pHeader->pHeap);
		MFDebug_Assert(pNew, "Failed to allocate memory!");
		if(!pNew)
			return NULL;

		MFCopyMemory(pNew, pMem, MFMin(bytes, (size_t)pHeader->size));
		MFHeap_Free(pMem);
		return pNew;
	}
	else
	{
		return MFHeap_AllocInternal(bytes, NULL);
	}
}
Example #5
0
MF_API void MFCollision_BuildField(MFCollisionItem *pField)
{
	MFCollisionField *pFieldData = (MFCollisionField*)pField->pTemplate;

	int numItems = pFieldData->itemList.GetLength();

	if(numItems <= 0)
	{
		MFDebug_Warn(4, "EmptyField can not be generated.");
		return;
	}

	// find the min and max range of the objects
	MFVector fieldMin = MakeVector(10e+30f), fieldMax = MakeVector(-10e+30f);

	MFCollisionItem **ppI = pFieldData->itemList.Begin();

	while(*ppI)
	{
		MFCollisionItem *pI = *ppI;
		MFCollisionTemplate *pT = pI->pTemplate;

		MFVector tMin = ApplyMatrixH(pT->boundingVolume.min, pI->worldPos);
		MFVector tMax = ApplyMatrixH(pT->boundingVolume.max, pI->worldPos);

		fieldMin = MFMin(fieldMin, tMin);
		fieldMax = MFMax(fieldMax, tMax);

		ppI++;
	}

	pFieldData->fieldMin = fieldMin;
	pFieldData->fieldMax = fieldMin;

	MFVector numCells;
	MFVector fieldRange = fieldMax - fieldMin;
	numCells.Rcp3(pFieldData->cellSize);
	numCells.Mul3(fieldRange, numCells);

	pFieldData->width = (int)MFCeil(numCells.x);
	pFieldData->height = (int)MFCeil(numCells.y);
	pFieldData->depth = (int)MFCeil(numCells.z);

	// this is TOTALLY broken!! .. if a big object lies in many cell's, it could easilly overflow the array.
	int totalCells = pFieldData->width * pFieldData->height * pFieldData->depth;
	int numPointers = totalCells * 2 + numItems * 16;

	MFCollisionItem **ppItems = (MFCollisionItem**)MFHeap_Alloc(sizeof(MFCollisionItem*) * numPointers);
	pFieldData->pppItems = (MFCollisionItem***)ppItems;
	ppItems += totalCells;

	for(int z=0; z<pFieldData->depth; z++)
	{
		for(int y=0; y<pFieldData->height; y++)
		{
			for(int x=0; x<pFieldData->width; x++)
			{
				pFieldData->pppItems[z*pFieldData->height*pFieldData->width + y*pFieldData->width + x] = ppItems;

				MFVector thisCell = fieldMin + pFieldData->cellSize * MakeVector((float)x, (float)y, (float)z);
				MFVector thisCellEnd = thisCell + pFieldData->cellSize;

				MFCollisionItem **ppI = pFieldData->itemList.Begin();

				while(*ppI)
				{
					MFCollisionItem *pI = *ppI;
					MFCollisionTemplate *pT = pI->pTemplate;

					// if this item fits in this cell, insert it into this cells list.
					MFVector tMin = ApplyMatrixH(pT->boundingVolume.min, pI->worldPos);
					MFVector tMax = ApplyMatrixH(pT->boundingVolume.max, pI->worldPos);

					// test of bounding boxes overlap
					if(MFCollision_TestAABB(tMin, tMax, thisCell, thisCellEnd))
					{
						*ppItems = pI;
						++ppItems;
					}

					ppI++;
				}

				*ppItems = NULL;
				++ppItems;
			}
		}
	}

	MFHeap_ValidateMemory(pFieldData->pppItems);
}
Example #6
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);
}