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

📄 heap.c

📁 wince下的源代码集合打包
💻 C
字号:
/* *		NK Kernel heap code * *		Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. * * Module Name: * *		heap.c * * Abstract: * *		This file implements the NK kernel heap * *//* The kernel heap is designed to support objects which are smaller than one page   in length.  The design assumes that kernel objects are either a divisor of the   page size, or small enough that the remainder when the page size is divided by   the object size is very small.   The design of the heap is a structure (heapptr) which contains the size of each   object, whether the memory is to be zero'ed by the alloc routine for that object,   and a pointer to a list of pages.  Pages, once added to a pool, are never freed.   When a page is added to a pool, it is linked into the master pointer for that   pool as a linked list of objects.  Each object has as it's first DWORD a pointer   to the next object on the list.  So, to allocate an object, if the pointer it   non-null, the block pointed to is returned, and the new pointer is set to be   the first DWORD of where the pointer was pointing.  If the pointer is NULL, then   a new page is threaded onto the list, and the same procedure is followed.  When   an object is freed, it is simply added to the head of the list.  Because the   pool number is passed to the free and alloc routines, and since the block sizes   are fixed at compile time, it is very efficient time-wise. */#include "kernel.h"#define ALIGNED_SIZE(n) ((HEAP_SIZE ## n + 3) & ~3)#define HEAPENTRY(n) {ALIGNED_SIZE(n), 0, HEAP_NAME ## n, 0, 0, 0}heapptr_t heapptr[NUMARENAS] = {	HEAPENTRY(0),	HEAPENTRY(1),	HEAPENTRY(2),	HEAPENTRY(3),	HEAPENTRY(4),	HEAPENTRY(5),	HEAPENTRY(6),#if PAGE_SIZE == 4096	HEAPENTRY(7),#endif};DWORD dwIndex; // ptr to arena to receive tail of heap pageuint SmallestSize;LPBYTE GrabFirstPhysPage(DWORD dwCount);// Distrubute unusable bytes on the end of a heap page to the heap item// free lists.void FreeSpareBytes(LPBYTE lpb, uint size) {	DWORD index;	heapptr_t *hptr;	BOOL bDidFour;    DEBUGMSG(ZONE_MEMORY, (TEXT("FSB: %8.8lx (%d)\r\n"), lpb, size));    do {   	    index = dwIndex;    } while ((DWORD)InterlockedTestExchange(&dwIndex, index, (index+1)%NUMARENAS) != index);	if (size >= heapptr[3].size) {	   	InterlockedPushList(&heapptr[3].fptr, lpb);		InterlockedIncrement(&heapptr[3].cMax);       	size -= heapptr[3].size;       	lpb += heapptr[3].size;	}    bDidFour = 0;	while (size >= SmallestSize) {	    hptr = &heapptr[index];	    if ((size >= hptr->size) && (!bDidFour || (index != 4))) {	    	InterlockedPushList(&hptr->fptr, lpb);			InterlockedIncrement(&hptr->cMax);        	size -= hptr->size;        	lpb += hptr->size;	    }	    if (index == 4)	    	bDidFour = 1;		index = (index+1) % NUMARENAS;	}    DEBUGMSG(ZONE_MEMORY, (TEXT("FSB: waste=%d\r\n"), size));    KInfoTable[KINX_HEAP_WASTE] += size;}// Initialize the kernel heapvoid HeapInit(void) {	int loop;	KInfoTable[KINX_KHEAP] = (long)heapptr;	/* Find the smallest size of block. */	SmallestSize = heapptr[0].size;	for (loop = 0; loop < NUMARENAS; loop++) {		DEBUGMSG(ZONE_MEMORY,(TEXT("HeapInit: Entry %2.2d, size %4.4d\r\n"),loop, heapptr[loop].size));	    DEBUGCHK((heapptr[loop].size & 3) == 0);	    if (heapptr[loop].size < SmallestSize)	        SmallestSize = heapptr[loop].size;	}   	KInfoTable[KINX_HEAP_WASTE] = 0;}LPBYTE pFree;DWORD dwLen;LPVOID GetKHeap(DWORD size) {	LPBYTE pRet, pNeedsFree;	DWORD dwNeedsFreeLen;	pRet = 0;	INTERRUPTS_OFF();	if (dwLen >= size) {		pRet = pFree;		dwLen -= size;		pFree += size;		INTERRUPTS_ON();	} else {		INTERRUPTS_ON();		if (pRet = (LPBYTE)KCall((PKFN)GrabFirstPhysPage,1)) {			InterlockedIncrement(&KInfoTable[KINX_SYSPAGES]);			pNeedsFree = pRet + size;			dwNeedsFreeLen = PAGE_SIZE - size;			INTERRUPTS_OFF();			if (dwLen < PAGE_SIZE - size) {				pNeedsFree = pFree;				dwNeedsFreeLen = dwLen;				pFree = pRet + size;				dwLen = PAGE_SIZE - size;			}			INTERRUPTS_ON();			FreeSpareBytes(pNeedsFree,dwNeedsFreeLen);		}	}	return pRet;}// Allocate a block from the kernel heapLPVOID AllocMem(ulong poolnum) {	LPBYTE pptr;	heapptr_t *hptr;	DEBUGCHK(poolnum<NUMARENAS);	hptr = &heapptr[poolnum];	if (!(pptr = InterlockedPopList(&hptr->fptr))) {		if (!(pptr = GetKHeap(hptr->size)))			return 0;		InterlockedIncrement(&hptr->cMax);	}	InterlockedIncrement(&hptr->cUsed);	return pptr;}// Free a block from the kernel heapVOID FreeMem(LPVOID pMem, ulong poolnum) {	heapptr_t *hptr;	DEBUGCHK(poolnum<NUMARENAS);	hptr = &heapptr[poolnum];#ifdef DEBUG	memset(pMem,0xab,hptr->size);#endif   	InterlockedPushList(&hptr->fptr, pMem);	InterlockedDecrement(&hptr->cUsed);}LPName AllocName(DWORD dwLen) {	WORD wPool, wBestLen = 0xffff, wBestPool = 0;	LPName lpn;	dwLen += 2; // for pool number	DEBUGCHK(dwLen <= (2+(MAX_PATH*2)));	for (wPool = 0; wPool < NUMARENAS; wPool++) {		if ((heapptr[wPool].size >= dwLen) && (heapptr[wPool].size < wBestLen)) {			wBestLen = heapptr[wPool].size;			wBestPool = wPool;		}	}	lpn = AllocMem(wBestPool);	if (lpn)		lpn->wPool = wBestPool;	return lpn;}

⌨️ 快捷键说明

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