?? mem.c
字號:
/**********************************************************************************
* 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 + -