⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.c

📁 samsung 9908DVD源代码,
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************************
 * mem.c
 * coded by hspark@ce.cnu.ac.kr
 * date : 2001/06/23
 * modified by hjahn@ce.cnu.ac.kr
 * date : 2003/03/03
 **********************************************************************************/


#include "kernel\\mk_sys.h"
#include "util\\mk_lib.h"
#include "kernel\\mk_mem.h"
#include "kernel\\mk_task.h"
#include "kernel\\mk_ddi.h"

struct mk_heap_struct *MK_pHeapListHead;
struct mk_heap_struct *MK_pHeapListTail;

struct mk_buffer_pool_struct *MK_pBufferPoolListHead;
struct mk_buffer_pool_struct *MK_pBufferPoolListTail;

VOID
MK_MemoryInitialize(VOID)
{
	MK_pHeapListHead = MK_NULL;
	MK_pHeapListTail = MK_NULL;
	MK_pBufferPoolListHead = MK_NULL;
	MK_pBufferPoolListTail = MK_NULL;
}

STATUS
MK_CreateHeapManager(MK_HEAP *pHeap, CHAR *pName, VOID *pAddr, unsigned long Length, ULONG MinSize, BOOLEAN Options)
{
	MK_MBLOCK	*pMBlock, *pRealBlock;
	INT			Flags;

	if(pHeap->h_Magic == MK_HEAP_MAGIC)
	{
#if MK_DEBUG_PRINT
		MK_Panic("MK_CreateHeapManager() - Magic error!\n");
#endif
		return MK_ERROR;
	}
	

	if((ULONG)pAddr & 1)	/* if pAddr isn't Word Align */
	{
#if MK_DEBUG_PRINT
		MK_InfoPrintf(MK_TASK_WARNING, "MK_CreateHeapManager() - It is not word align! Task(%s)\n", MK_GetCurrentTask()->t_pName);
#endif
		return MK_WORDALIGN_ERROR;
	}
	
	if(Length < sizeof(MK_MBLOCK)*2)
	{
#if MK_DEBUG_PRINT
		MK_InfoPrintf(MK_TASK_WARNING, "MK_CreateHeapManager() - Memory is not enough to create heap! Task(%s)\n", MK_GetCurrentTask()->t_pName);
#endif
		return MK_SMALLMEMORY_ERROR;
	}

	//MK_BlockCopy(pHeap->h_pName, pName, MK_NAME_MAX-1);
	//pHeap->h_pName[MK_NAME_MAX-1] = '\0';
	pHeap->h_pName = pName;

	/* Initialize Real Heap Area which will be allocated */
	pRealBlock = (MK_MBLOCK *)pAddr + 1;
	pRealBlock->mb_pNext = MK_NULL;
	pRealBlock->mb_Size = Length - sizeof(MK_MBLOCK);
	pRealBlock->mb_Magic  = (ULONG)pHeap;

	/* make a Head Memory Block which is not merged */
	pMBlock = (MK_MBLOCK *)pAddr;
	pMBlock->mb_Size = 0;
	pMBlock->mb_pNext = pRealBlock ;
	pMBlock->mb_Magic = (ULONG)pHeap;

	pHeap->h_StartofHeap = (ULONG)pAddr;
	pHeap->h_HeapSize = Length;
	pHeap->h_FreeSize = Length;
	pHeap->h_MinSize = MinSize > sizeof(MK_MBLOCK) ? MinSize : sizeof(MK_MBLOCK);
	pHeap->h_pFreeMBlockList = pMBlock;

#if 0
	pHeap->h_FreeMBlockList.mb_pNext = pMBlock;
	pHeap->h_FreeMBlockList.mb_Size = 0;		/* Prevent Header allocated */
#endif /* 0 */

	pHeap->h_Options = Options;

	MK_CreatePendingList(&pHeap->h_PendingList, Options);

	pHeap->h_Magic = MK_HEAP_MAGIC;

	Flags = MK_InterruptDisable();		/* Critical Region */

	pHeap->h_pNext = MK_NULL;
	pHeap->h_pPrev = MK_NULL;
	if(MK_pHeapListHead == MK_NULL)
	{
		MK_pHeapListHead = pHeap;
		MK_pHeapListTail = pHeap;
	}
	else
	{
		pHeap->h_pPrev = MK_pHeapListTail;
		MK_pHeapListTail->h_pNext = pHeap;
		MK_pHeapListTail = pHeap;
	}

	MK_InterruptRestore(Flags);

	return MK_NO_ERROR;
}

STATUS
MK_DeleteHeapManager(MK_HEAP *pHeap)
{
	INT Flags;

	if(pHeap->h_Magic != MK_HEAP_MAGIC)
	{
#if MK_DEBUG_PRINT
		MK_Panic("MK_DeleteHeapManager() - Magic Error! Task(%s)\n", MK_GetCurrentTask()->t_pName);
#endif
		return MK_RESOURCE_ERROR;
	}

	Flags = MK_InterruptDisable();		/* Critical Region */

	pHeap->h_Magic = 0;

	MK_ClearPendingList(&pHeap->h_PendingList);

	if(MK_pHeapListHead == MK_pHeapListTail)
	{
		MK_pHeapListHead = MK_NULL;
		MK_pHeapListTail = MK_NULL;
	}
	else
	{
		if(pHeap == MK_pHeapListHead)
		{
			MK_pHeapListHead = pHeap->h_pNext;
			MK_pHeapListHead->h_pPrev = MK_NULL;
		}
		else if(pHeap == MK_pHeapListTail)
		{
			MK_pHeapListTail = pHeap->h_pPrev;
			MK_pHeapListTail->h_pNext = MK_NULL;
		}
		else
		{
			pHeap->h_pPrev->h_pNext = pHeap->h_pNext;
			pHeap->h_pNext->h_pPrev = pHeap->h_pPrev;
		}
	}
	pHeap->h_pNext = MK_NULL;
	pHeap->h_pPrev = MK_NULL;

	MK_InterruptRestore(Flags);

	return MK_NO_ERROR;
}

STATUS
MK_ResetHeapManager(MK_HEAP *pHeap)
{
	MK_MBLOCK *pMBlock, *pRealBlock;
	INT	Flags;

	if(pHeap->h_Magic != MK_HEAP_MAGIC)
	{
#if MK_DEBUG_PRINT
		MK_Panic("MK_ResetHeapManager() - Magic error!\n");
#endif
		return MK_RESOURCE_ERROR;
	}
	
	Flags = MK_InterruptDisable();

	/* Initialize Real Heap Area which will be allocated */
	pRealBlock = (MK_MBLOCK *)pHeap->h_StartofHeap + 1;
	pRealBlock->mb_pNext = MK_NULL;
	pRealBlock->mb_Size = pHeap->h_HeapSize - sizeof(MK_MBLOCK);
	pRealBlock->mb_Magic  = (ULONG)pHeap;

	/* make a Head Memory Block which is not merged */
	pMBlock = (MK_MBLOCK *)pHeap->h_StartofHeap;
	pMBlock->mb_Size = 0;
	pMBlock->mb_pNext = pRealBlock ;
	pMBlock->mb_Magic = (ULONG)pHeap;

	pHeap->h_pFreeMBlockList = pMBlock;

	MK_ClearPendingList(&pHeap->h_PendingList);
	
	MK_InterruptRestore( Flags );
	return MK_NO_ERROR;
}

static STATUS 
MK_GetMemoryInternal(MK_HEAP *pHeap, VOID **pAddr, ULONG Size)
{
	MK_MBLOCK *pPrev, *pNext, *pLeft;
	MK_MBLOCK_DUMMY *pInfo;
	ULONG AllocSize;
	int Flags;

	Flags = MK_InterruptDisable();
	
	if(Size < pHeap->h_MinSize)
	{
		AllocSize = pHeap->h_MinSize;
	}
	else
	{
		AllocSize = Size;
	}
	AllocSize += sizeof(MK_MBLOCK_DUMMY);
	AllocSize = MK_RoundWord(AllocSize);

	/* First Fit Algorithm */
	pPrev = pHeap->h_pFreeMBlockList;
	pNext = pPrev->mb_pNext;

#if 0
	for( ; pNext != MK_NULL; pPrev = pNext, pNext = pNext->mb_pNext)
	{
		if( ( pNext->mb_Size > AllocSize ) && ( pNext->mb_Size <= AllocSize + sizeof(MK_MBLOCK)) )
		{
			AllocSize = pNext->mb_Size;
			pPrev->mb_pNext = pNext->mb_pNext;
			pInfo = (MK_MBLOCK_DUMMY *)pNext;
			pInfo->md_pHeap = pHeap;
			pInfo->md_Size = AllocSize;
			*pAddr = (VOID *)(pInfo+1);

			MK_InterruptRestore(Flags);
			return MK_NO_ERROR;
		}
		else if( pNext->mb_Size > AllocSize + sizeof(MK_MBLOCK) )
		{
			pLeft = (MK_MBLOCK *)( (UINT)pNext + AllocSize );
			pPrev->mb_pNext = pLeft;
			pLeft->mb_Magic = (UINT)pHeap;
			pLeft->mb_pNext = pNext->mb_pNext;
			pLeft->mb_Size = pNext->mb_Size - AllocSize;
			pInfo = (MK_MBLOCK_DUMMY *)pNext;
			pInfo->md_pHeap = pHeap;
			pInfo->md_Size = AllocSize;
			*pAddr = (VOID *)(pInfo + 1);

			MK_InterruptRestore(Flags);
			return MK_NO_ERROR;
		}
	}
#else 

	for( ; pNext != MK_NULL; pPrev = pNext, pNext = pNext->mb_pNext)
	{
		if( pNext->mb_Size > AllocSize ) 
		{
			if( pNext->mb_Size <= AllocSize + sizeof(MK_MBLOCK)) 
			{
				AllocSize = pNext->mb_Size;
				pPrev->mb_pNext = pNext->mb_pNext;
				pInfo = (MK_MBLOCK_DUMMY *)pNext;
				pInfo->md_pHeap = pHeap;
				pInfo->md_Size = AllocSize;
				*pAddr = (VOID *)(pInfo+1);

				MK_InterruptRestore(Flags);
				return MK_NO_ERROR;
			}
		    else 
			{
				pLeft = (MK_MBLOCK *)( (ULONG)pNext + AllocSize );
				pPrev->mb_pNext = pLeft;
				pLeft->mb_Magic = (ULONG)pHeap;
				pLeft->mb_pNext = pNext->mb_pNext;
				pLeft->mb_Size = pNext->mb_Size - AllocSize;
				pInfo = (MK_MBLOCK_DUMMY *)pNext;
				pInfo->md_pHeap = pHeap;
				pInfo->md_Size = AllocSize;
				*pAddr = (VOID *)(pInfo + 1);

				MK_InterruptRestore(Flags);
				return MK_NO_ERROR;
			}
		}
	}
#endif

	*pAddr = 0;

#if MK_DEBUG_PRINT
	MK_InfoPrintf(MK_TASK_WARNING, "MK_GetMemoryInternal() - Memory is not allocated! Task(%s)\n", MK_GetCurrentTask()->t_pName);
#endif

	MK_InterruptRestore(Flags);
	
	return MK_ERROR;
}

STATUS
MK_GetMemory(MK_HEAP *pHeap, VOID **pAddr, ULONG Size, LONG Ticks)
{
	MK_TASK *pTask;
	STATUS	Status;
	INT		Flags;

	if(pHeap->h_Magic != MK_HEAP_MAGIC)
	{
		*pAddr = 0;
#if MK_DEBUG_PRINT
		MK_Panic("MK_GetMemory() - Magic Error! Task(%s)\n", MK_GetCurrentTask()->t_pName);
#endif
		return MK_RESOURCE_ERROR;
	}

	Flags = MK_InterruptDisable();		/* Critical Region */
	
	Status = MK_GetMemoryInternal(pHeap, pAddr, Size);
	if( Status >= 0 )
	{
		MK_InterruptRestore(Flags);
		return Status;
	}

	if(Ticks == MK_NO_WAIT)
	{
		MK_KernelInfoPrintf((MK_TASK_WARNING, "MK_GetMemory() - Memory is not allocated(MK_TIMEOUT)! Task(%s)\n",
						MK_GetCurrentTask()->t_pName));
		MK_InterruptRestore(Flags);
		return MK_TIMEOUT;
	}

	pTask = MK_GetCurrentTask();
	pTask->t_pendingMemSize = (ULONG)Size;

	MK_DeleteTaskFromReadyList(pTask);
	MK_InsertTaskToPendingList(&pHeap->h_PendingList, pTask);
	if(Ticks > 0)
	{
		MK_InsertTaskToDelayedList(pTask, Ticks);
	}

	MK_Schedule();

	if(pTask->t_Status & MK_TASK_FORCED)
	{
		pTask->t_Status &= ~MK_TASK_FORCED;

		MK_KernelInfoPrintf((MK_TASK_WARNING, "MK_GetMemory() - Heap is deleted by force! Task(%s)\n",
					MK_GetCurrentTask()->t_pName));
		MK_InterruptRestore(Flags);
		return MK_RESOURCE_ERROR;
	}
	/* When this Task is released */

	if(pTask->t_Status & MK_TASK_PENDING)	/* released by TIMEOUT */
	{
		MK_DeleteTaskFromPendingList(&pHeap->h_PendingList, pTask);

		MK_KernelInfoPrintf((MK_TASK_WARNING, "MK_GetMemory() - Memory is not allocated by timeout! Task(%s)\n", MK_GetCurrentTask()->t_pName));
		MK_InterruptRestore(Flags);
		return MK_TIMEOUT;
	}
	/* else can Get the Meomry */
	Status = MK_GetMemoryInternal(pHeap, pAddr, Size);

#if 1
	pTask = MK_GetFirstPendingTask(&pHeap->h_PendingList);
	if(MK_GetHeapMaxMemorySize(pHeap) >= (ULONG)pTask->t_pendingMemSize)
	{
		MK_DeleteTaskFromPendingList(&pHeap->h_PendingList, pTask);
		if(pTask->t_Status & MK_TASK_DELAYED)
		{
			MK_DeleteTaskFromDelayedList(pTask);
		}
		MK_InsertTaskToReadyList(pTask);
	}
#endif

	MK_InterruptRestore(Flags);
	return Status;
}

UINT
MK_GetHeapMaxMemorySize(MK_HEAP *pHeap)
{
	MK_MBLOCK *pMBlock;
	UINT	MaxSize = 0;
	INT		flag;

	if(pHeap->h_Magic != MK_HEAP_MAGIC)
	{
#if MK_DEBUG_PRINT
		MK_Panic("MK_GetHeapMaxMemorySize() - Magic Error! Task(%s)\n", MK_GetCurrentTask()->t_pName);
#endif
		return 0;
	}

	flag = MK_InterruptDisable();

	pMBlock = pHeap->h_pFreeMBlockList->mb_pNext;
	while(pMBlock != 0)
	{
		MaxSize = (MaxSize >= pMBlock->mb_Size) ? MaxSize : pMBlock->mb_Size;
		pMBlock = pMBlock->mb_pNext;
	}
	
	MK_InterruptRestore(flag);
	return MaxSize;
}

static STATUS 
MK_FreeMemoryInternal(MK_HEAP *pHeap, VOID *pAddr, ULONG AllocSize, ULONG *pMergedSize)
{
	MK_MBLOCK *pPrev, *pNext;
	MK_MBLOCK *pMBlock;
	ULONG	Top;
	INT		Flags;

	Flags = MK_InterruptDisable();
	
	pPrev = pHeap->h_pFreeMBlockList;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -