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

📄 vm1_kmalloc.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
字号:
/***************************************************************************
**     File name   : vm1_kmalloc.c
**     Author      : x.cheng
**     Create date :
**
**	   Comment:
**        virtual memory manage module - kernel space malloc function
**
**     Revisions:
**     $Log: vm1_kmalloc.c,v $
**     Revision 1.4  2005/08/05 15:13:25  x.cheng
**     heap info display function upgrade...
**
**     Revision 1.3  2005/08/02 15:39:35  x.cheng
**     new debug function Vm1KeDumpHeapStatus()
**
**     Revision 1.2  2005/07/30 09:00:20  x.cheng
**     bug fix for kemalloc function...
**
**     Revision 1.1.1.1  2005/07/27 06:53:16  x.cheng
**     add into repositories
**
**
***************************************************************************/
#include "const.h"
#include "type.h"
#include "stdarg.h"
#include "stdlib.h"

#include "..\..\Inc\i386\map.h"		//kernel\inc\i386
#include "..\..\Inc\i386\system.h"		
#include "..\..\Inc\i386\page.h"
#include "..\..\Inc\tui.h"
#include "..\..\Inc\pmm.h"
#include "..\..\Inc\mts.h"
#include "..\..\Inc\keyb.h"
#include "..\..\Inc\debug.h"

#define __VMM_SRC__
#include "..\inc\def_vmm.h"			//kernel\vmm\inc

/* debug preprocessor instrument
	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
				
	#endif
	#endif	
***************************/

/************************************************************
*************************************************************
**      Function Name:			pvVm1KeMalloc
**      Author:                 x.cheng
**
**      Comment:
**			从内核堆内存空间分配内存,使用First-Fit算法
**   
**       
**
**      List of parameters:
**			 unsigned long - 需要分配内存的大小 
**			 int - 分配内存后要做的动作
**      Return value:   
**			  指向已分配内存空间的首指针
**
**      Revisions:
**
*************************************************************
*************************************************************/
void *pvVm1KeMalloc(unsigned long ulSize, int iFlag)
{
	ts_MCB *pstSearch, *pstBest=NULL;
	unsigned long ulFlags;

	if (!ulSize)    return NULL;	//0 size

	// 实际分配中,应该+sizeof(ts_MCB),最小的分配的单位也是sizeof(ts_MCB)
	ulSize = ( ulSize & -(sizeof(ts_MCB)) ) + sizeof(ts_MCB);
	pstSearch = (ts_MCB*)KERNEL_HEAP_START_ADDRESS;

	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
//		POSITION();
	#endif
	#endif	

	SaveEflagsAndCli(ulFlags);	//macro  in system.h

	while (pstSearch < (ts_MCB *)KERNEL_HEAP_END_ADDRESS) {
		/* find a free block */
		if ( MB_FREE == pstSearch->ulFlags ) {
			// block is free, then...
			if ( pstSearch->ulSize >= ulSize ) {
				//found an enough block, lucky
				pstBest = pstSearch;
				break;
			}
		}
		//examine the next memory block
		pstSearch = (void *)pstSearch + pstSearch->ulSize + sizeof(ts_MCB);
	}
	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
//		POSITION();
	#endif
	#endif	

	//have you found a free block?
	if ( NULL == pstBest ) {
		//out of memroy
		RestoreEflags(ulFlags);
		return NULL;
	}

	//if the block greater then ulSize, split it
	if (pstBest->ulSize != ulSize) {
		ts_MCB *pstNew = (void *)pstBest + sizeof (ts_MCB) + ulSize;
		pstNew->ulMagic = MCB_MAGIC;
		pstNew->ulFlags = MB_FREE;
		pstNew->ulSize  = pstBest->ulSize - ulSize - sizeof(ts_MCB);
		pstNew->ulOwnerPtr = NULL;

		pstBest->ulSize = ulSize;
	}

	//allocate the block and busy it
	pstBest->ulMagic = MCB_MAGIC;
	pstBest->ulFlags = MB_BUSY;

	if( iFlag == GFP_KERNEL ) {
		if ( g_pstCurrentTask == NULL )
			pstBest->ulOwnerPtr = NULL;   //fake....
		else
			pstBest->ulOwnerPtr = g_pstCurrentTask->iPid;
	} else {
		// kmalloc() during interrupt! the owner is ambiguous.
		pstBest->ulOwnerPtr = NULL;
	}
	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
		kprintf("%s(): size= %ld at %p\n", __FUNCTION__, ulSize, pstBest);
	#endif
	#endif	 
	//kprintf("%s(): size= %ld at %p\n", __FUNCTION__, ulSize, pstBest);
	//return the first-fit pointer
	pstBest = (void*)pstBest + sizeof(ts_MCB);
	RestoreEflags(ulFlags);

	/* 返回的地址中刚刚除掉了MCB */
	return (void *)pstBest;
}

/************************************************************
*************************************************************
**      Function Name:			vVm1KeFree
**      Author:                 x.cheng
**
**      Comment:
**			释放由pvKeMalloc分配的堆内存
**   并尽可能的把邻接空闲分区合并
**       
**
**      List of parameters:
**			 void * - 指向由pvKeMalloc分配的内存
**
**      Return value:   
**			  none
**
**      Revisions:
**
*************************************************************
*************************************************************/
void vVm1KeFree(void *pvPtr)
{
	ts_MCB *pstSearch, *pstNext, *pstPre;
	unsigned long ulFlags;

	if ( NULL == pvPtr ) return;

	//pointer to the header
	pstSearch = (void *)pvPtr - sizeof(ts_MCB);

	if ( MCB_MAGIC != pstSearch->ulMagic )	return;
	if ( MB_BUSY != pstSearch->ulFlags ) return;

	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
		kprintf("%s(): size= %ld at %p\n", __FUNCTION__, pstSearch->ulSize, pstSearch);
	#endif
	#endif	 
	SaveEflagsAndCli(ulFlags);

	pstSearch->ulFlags = MB_FREE;
	pstSearch->ulOwnerPtr = NULL;

	//try to combine the block with the next one
	pstNext = (void *)pstSearch + pstSearch->ulSize + sizeof(ts_MCB);
	if (pstNext < (ts_MCB *)KERNEL_HEAP_END_ADDRESS ) {
		if ( MB_FREE == pstNext->ulFlags ) {
			//merge the two block
			pstSearch->ulSize += pstNext->ulSize + sizeof(ts_MCB);
			pstNext->ulMagic = NULL;
		}
	}
	
	//try to combine the block with the pre one
	if (pstSearch != (ts_MCB *)KERNEL_HEAP_START_ADDRESS ) {
		//find the pre block
		pstPre = (ts_MCB *)KERNEL_HEAP_START_ADDRESS;
		for(;;) {
			if ( ((void *)pstPre + pstPre->ulSize + sizeof(ts_MCB)) == pstSearch ) {
				//block found!
				if ( MB_FREE == pstPre->ulFlags ) {
					//and it's a free block
					//merge them
					pstPre->ulSize += (pstSearch->ulSize + sizeof(ts_MCB));
					pstSearch->ulMagic = NULL;
					pstSearch = pstPre;
				}
				break;
			}
			pstPre = (void *)pstPre + pstPre->ulSize + sizeof(ts_MCB);
		}
	}

	//Release the physical space occupied by the block
	
	{	//deallocate(pstSearch);
		unsigned long ulStart = ulPageUpAlign( (unsigned long)((void *)pstSearch + sizeof(ts_MCB)) );
		unsigned long ulEnd = ulPageDownAlign( (unsigned long)((void *)pstSearch + sizeof(ts_MCB) + pstSearch->ulSize) );

		while( ulStart < ulEnd) {
			if ( *pulAddressToPde(ulStart) != NULL) {
				vPmmFreeOnePage(ulStart);
				ulStart += PAGE_SIZE;
			} else {
				ulStart = ulPageDirUpAlign(ulStart);
			}
		}
	}

	RestoreEflags(ulFlags);
}


/************************************************************
*************************************************************
**      Function Name:			pvVm1KeAlignMalloc
**      Author:                 x.cheng
**
**      Comment:
**			分配的堆内存,按要求对齐
**       exception: out of memory
**
**      List of parameters:
**			 ulAlign - 对齐边界
**			 ulSize  - 分配空间的大小
**			 iFlags  - 
**
**      Return value:
**			A pointer to a memory area aligned to the boundary.	   
**		 返回的内存地址总是在ulAlign的边界上的!比如0xD0001000
**      Revisions:
**
*************************************************************
*************************************************************/
void *pvVm1KeAlignMalloc(unsigned long ulAlign, unsigned long ulSize, int iFlags)
{
	ts_MCB *pstTmp1, *pstTmp2;

	if (!ulSize) return NULL;
	//malloc invoke
	pstTmp1 = (ts_MCB *)pvVm1KeMalloc(ulSize+ulAlign+2*sizeof(ts_MCB), iFlags);
	if (NULL == pstTmp1) return NULL;
	if ( 0 == ulAlign )	return (void *)pstTmp1;

	//看看对齐了吗?
	if ( (unsigned long)pstTmp1 % ulAlign ) {
		//对齐它...
		unsigned long ulFlags;

		SaveEflagsAndCli(ulFlags);

		//new allocate
		pstTmp2 = pstTmp1 + 2;
		pstTmp2 = (ts_MCB *)pulAlignUp( (unsigned long)pstTmp2, ulAlign) - 1;
		pstTmp2->ulMagic = MCB_MAGIC;
		pstTmp2->ulFlags = (pstTmp1-1)->ulFlags;
		pstTmp2->ulOwnerPtr = (pstTmp1-1)->ulOwnerPtr;
		//p2->size = mem_sizeof(p) - ((size_t)(p2+1) - (size_t)p);
		pstTmp2->ulSize = (pstTmp1-1)->ulSize - ( (unsigned long)(pstTmp2+1) - (unsigned long)pstTmp1);

		// free the unuse space.
		(pstTmp1-1)->ulSize = (unsigned long)pstTmp2 - (unsigned long)pstTmp1;
		
		RestoreEflags(ulFlags);

		vVm1KeFree( (void *)pstTmp1 );

	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
		kprintf("%s(): size= %ld align= %d, at %p\n", __FUNCTION__, ulSize, ulAlign, pstTmp2+1);
	#endif
	#endif	 
		return( pstTmp2 + 1 );
	}

	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
		kprintf("%s(): size= %ld align= %d, at %p\n", __FUNCTION__, ulSize, ulAlign, pstTmp1);
	#endif
	#endif	 
	//对齐了的!
	return (pstTmp1);
}

/************************************************************
*************************************************************
**      Function Name:			vVm1KeMallocInit
**      Author:                 x.cheng
**
**      Comment:
**			内核堆内存分配初始化
**   
**       
**
**      List of parameters:
**			  - 
**
**      Return value:   
**			  no
**
**      Revisions:
**
*************************************************************
*************************************************************/
void vVm1KeMallocInit()
{
	ts_MCB *pstFirstMCB;

	#ifdef _DEBUG__
	#ifdef _DEBUG_VMM__
		kprintf("\t--initial alloctor for kernel heap area...");				
		vDbgDummy();
	#endif
	#endif	 
	vSTI();
	// Create only one hudge block					//
	pstFirstMCB = (ts_MCB*)KERNEL_HEAP_START_ADDRESS;
	pstFirstMCB->ulMagic = MCB_MAGIC;
	pstFirstMCB->ulFlags = MB_FREE;
	pstFirstMCB->ulSize = KERNEL_HEAP_END_ADDRESS - KERNEL_HEAP_START_ADDRESS - sizeof(ts_MCB);
	pstFirstMCB->ulOwnerPtr = NULL;

}



/************************************************************
*************************************************************
**      Function Name:			Vm1KeDumpHeapStatus
**      Author:                 x.cheng
**
**      Comment:
**			dump heap的分配情况
**   
**       
**
**      List of parameters:
**			  - 
**
**      Return value:   
**			  no
**
**      Revisions:
**
*************************************************************
*************************************************************/
void Vm1KeDumpHeapStatus(void)
{
	ts_MCB *pstSearch;
	unsigned long ulFlags;
	int iRow;

	pstSearch = (ts_MCB*)KERNEL_HEAP_START_ADDRESS;

	kprintf("\nMCB\t\tflags\t\tsize\t\towner\n");
	SaveEflagsAndCli(ulFlags);	//macro  in io.h

	while (pstSearch < (ts_MCB *)KERNEL_HEAP_END_ADDRESS) {
		kprintf("%p\t\t%ld\t\t%ld\t\t%ld\n", pstSearch, pstSearch->ulFlags, pstSearch->ulSize, pstSearch->ulOwnerPtr);
		if ( ++iRow > 21 ) {
			kprintf("Press any key to continue, CTRL+C exit...\n");
			if( iKeybGetChar() == CTRL_C )
				break;
			iRow = 0;
		}

		//examine the next memory block
		pstSearch = (void *)pstSearch + pstSearch->ulSize + sizeof(ts_MCB);
	}
	kprintf("====================================================================\n");
}

⌨️ 快捷键说明

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