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

📄 klheap.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
返回值:
	假如成功,返回TRUE; 否则返回FALSE
功能描述:
	检验的指针是否合法
引用:
	
************************************************/
#define DEBUG_IsPtrValid 1
static BOOL IsPtrValid( LPCVOID lpvUsed, LPBLOCK * lppRet, LPBLOCK * lpxRet )
{
	LPBLOCK p, x;

    p = (LPBLOCK)((char*)lpvUsed - sizeof(BUSY));
    if ( !IS_BUSY(p) )
    {   // 无效的指针
		WARNMSG( DEBUG_IsPtrValid, ( "error0: invalid ptr(0x%x),(p=0x%x).\r\n" , lpvUsed, p ) );
        KL_SetLastError( ERROR_INVALID_PARAMETER );
        //goto ret;
		return FALSE;
    }
    x = (LPBLOCK)((char*)p->busy.lpNext-(BUSY_FLAG+ALLOC_FLAG) );
    if ( !x || x->busy.lpPrev != p )
    {   // 无效的指针
        KL_SetLastError( ERROR_INVALID_PARAMETER );
		WARNMSG( DEBUG_IsPtrValid, ( "error1: invalid ptr(0x%x), x=0x%x.\r\n" , lpvUsed, x ) );
        //goto ret;
		return FALSE;
    }
	if( lppRet )
		*lppRet = p;
	if( lpxRet )
		*lpxRet = x;
	return TRUE;
}

/**************************************************
声明:BOOL WINAPI KL_HeapFree( HANDLE hHeap, DWORD dwFlags, void FAR * lpvUsed )
参数:
	hHeap - 堆句柄
	dwFlags - 功能,可以为以下值:
		HEAP_NO_SERIALIZE - 不需要串行化(互斥操作)
	lpvUsed - 之前分配的内存地址
返回值:
	假如成功,返回TRUE; 否则返回FALSE
功能描述:
	释放之前用KL_HeapAlloc 或KL_HeapRealloc返回的一个内存块
引用:
	系统API 
************************************************/
#define DEBUG_HEAPFREE 0
BOOL WINAPI KL_HeapFree( HANDLE hHeap, DWORD dwFlags, void FAR * lpvUsed )
{
    LPBLOCK p, x;
	BOOL bRetv = FALSE;
	LPHEAP lpHeap = (LPHEAP)hHeap;

	ASSERT_NOTIFY( lpvUsed, "Invalid param at _Free:" );

    if ( !lpvUsed ) return FALSE;

	//进入互斥段

	EnterCriticalLock( lpHeap, TRUE );
	
	DEBUGMSG( DEBUG_HEAPALLOC, ( "+++F(0x%x,lock=%d)F+++.\r\n", KL_GetCurrentThreadId(), lpHeap->iLockCount ) );
	if( IsPtrValid( lpvUsed, &p, &x ) == FALSE )
	{
		WARNMSG( DEBUG_HEAPFREE, ( "erro in KL_HeapFree: invalid ptr(0x%x).\r\n" , lpvUsed ) );
		goto ret;
	}

    p->busy.lpNext = x;

	x = p->busy.lpNext;
    
    if ( !IS_BUSY(x) ) 
	{ // 如果下一个块也是空闲的,则组合它们
		_RemoveFromFree( lpHeap, x );
		p->busy.lpNext = x->busy.lpNext;
		x->busy.lpNext->busy.lpPrev = p; 
	}
	
    if ( (x = p->busy.lpPrev) != 0 && !IS_BUSY(x) ) 
	{ // 如果前一个块也是空闲的,则组合它们
		_RemoveFromFree( lpHeap, x );
		x->busy.lpNext = p->busy.lpNext;
		p->busy.lpNext->busy.lpPrev = x;
		p = x; 
	}

    //将该块插入堆空闲链表
    _InsertToFree( lpHeap, p );

	bRetv = TRUE;

ret:
	//离开互斥段
    DEBUGMSG( DEBUG_HEAPALLOC, ( "---F(0x%x)F---.\r\n", KL_GetCurrentThreadId() ) );
    LeaveCriticalLock( lpHeap, TRUE );
	
	return bRetv;
}

/**************************************************
声明:LPVOID WINAPI KL_HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpOldPtr, DWORD nNewAllocSize )
参数:
	hHeap - 堆句柄
	dwFlags - 功能,可以为以下值:
		HEAP_NO_SERIALIZE - 不需要串行化(互斥操作)
	lpOldPtr - 之前已经分配的内存。如果是NULL,等同与KL_HeapAlloc
	nNewAllocSize - 需要重新分配的内存大小。 如果是0,等同与KL_HeapFree
返回值:
	假如成功,返回非NULL的指针; 否则返回NULL,不会改变之前的指针
功能描述:
	从堆里重新分配一个内存快
引用:
	系统API 
************************************************/
#define DEBUG_HEAPREALLOC 0
LPVOID WINAPI KL_HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpOldPtr, DWORD nNewAllocSize )
{
    register void *newp = 0;
    LPBLOCK p, next, x;
    register DWORD oldsz;
	LPHEAP lpHeap = (LPHEAP)hHeap;
	DWORD dwOldSizeSave = 0;
	
	// 如果是NULL,等同与KL_HeapAlloc
    if ( !lpOldPtr )
        return KL_HeapAlloc( lpHeap, dwFlags, nNewAllocSize );
	// 如果是0,等同与KL_HeapFree
    if ( !nNewAllocSize )
    {
        KL_HeapFree( lpHeap, dwFlags, lpOldPtr );
        return 0;
    }

    // 对齐
    nNewAllocSize = (nNewAllocSize + ALIGNMASK) & ~ALIGNMASK;
    
	//进入互斥段
	EnterCriticalLock( lpHeap, TRUE );

	if( IsPtrValid( lpOldPtr, &p, &next ) == FALSE )
	{
		WARNMSG( DEBUG_HEAPFREE, ( "erro in KL_HeapReAlloc: invalid ptr(0x%x).\r\n" , lpOldPtr ) );
		goto ret;
	}

	
	//得到尺寸(不包含头)
    dwOldSizeSave = oldsz = (char *)next - (char *)lpOldPtr;
	
    if ( oldsz >= nNewAllocSize ) 
	{  
		register DWORD sizeleft;
        // 新的内存需要小于之前分配的老的内存块,我们只需减少老的内存块
resize:
		sizeleft = oldsz - nNewAllocSize;  //释放某些bytes
		if ( sizeleft > sizeof(BLOCK) ) 
		{   // 将其插入空闲链表
			x = (LPBLOCK)((char*)next - sizeleft);
			x->busy.lpNext = next;
			x->busy.lpPrev = p;
			p->busy.lpNext = (LPBLOCK)( (char*)x+(BUSY_FLAG+ALLOC_FLAG) );
			next->busy.lpPrev = x;
			_InsertToFree( lpHeap, x );
			if ( !IS_BUSY(next) ) 
			{   //如果与下一个空闲块的地址是连续,则组合它们
				_RemoveFromFree( lpHeap, next );
				x->busy.lpNext = next->busy.lpNext;
				next->busy.lpNext->busy.lpPrev = x; 
			}
		}
		newp = lpOldPtr; 
	}
	
    else if ( !IS_BUSY(next) && (x=next->busy.lpNext) != 0 &&
		(oldsz = (char*)x - (char*)lpOldPtr) >= nNewAllocSize ) 
	{  //下一个块是空闲块并且其大小满足需要的尺寸
		_RemoveFromFree( lpHeap, next );
		p->busy.lpNext = (LPBLOCK)( (char*)x+(BUSY_FLAG+ALLOC_FLAG) );
		x->busy.lpPrev = p;
		next = x;
		goto resize; 
	}
	
    else if ( (x=p->busy.lpPrev) != 0 && !IS_BUSY(x) &&
		      (oldsz = (char*)next - ((char*)x+sizeof(BUSY))) >= nNewAllocSize )
	{
		char *from, *to; 
		DWORD n;
		//前一个块是空闲块并且其大小满足需要的尺寸
		_RemoveFromFree( lpHeap, x );
		x->busy.lpNext = (LPBLOCK)( (char*)next + (BUSY_FLAG+ALLOC_FLAG) );
		next->busy.lpPrev = x;
		from = (char*)p + sizeof(BUSY);
		to   = (char*)x + sizeof(BUSY);
		n = (char *)next - (char *)lpOldPtr;
        // 拷贝内容
		memmove( to, from, n );
		p = x;
		lpOldPtr = (char*)p + sizeof(BUSY);
		goto resize; 
	}
    else 
	{
		// 需要一个完全新的块
		LeaveCriticalLock( lpHeap, TRUE );//LN:2003-05-13, Add

        // 重新分配
		if ( !(newp = KL_HeapAlloc( lpHeap, dwFlags, nNewAllocSize ) ) ) //;Mem_Alloc( nNewAllocSize )) ) 
			return 0;
		// 拷贝内容
		memmove( newp, lpOldPtr, (char *)next - (char *)lpOldPtr );
		// 释放老的
		KL_HeapFree( lpHeap, dwFlags, lpOldPtr );
		return newp; 
	}
	
ret:

	//离开互斥段

	LeaveCriticalLock( lpHeap, TRUE );

	if( dwOldSizeSave < nNewAllocSize && (dwFlags & HEAP_ZERO_MEMORY ) )
	{   // 将多于的内存内容清为0
		memset( (char*)newp + dwOldSizeSave, 0, nNewAllocSize - dwOldSizeSave );
	}
    return newp;
}

/**************************************************
声明:int Heap_Enum( LPHEAP lpHeap, LPHEAPENUMPROC lpfn, LPARAM lParam, UINT uiFlag )

参数:
	lpHeap - HEAP结构指针
	lpfn - 枚举功能
	lParam - 传递给枚举功能的参数
	uiFlag - 保留
返回值:
	假如成功,返回TRUE; 否则返回FALSE
功能描述:
	枚举所有已分配的块
引用:
	
************************************************/

static int Heap_Enum( LPHEAP lpHeap, LPHEAPENUMPROC lpfn, LPARAM lParam, UINT uiFlag )
{
    LPBLOCK lpBlock, lpFirstBlock;

	EnterCriticalLock( lpHeap, TRUE );

	lpFirstBlock = lpBlock = lpHeap->lpFirstBlock;

	while( lpBlock )
	{
		if( IS_ALLOC(lpBlock) )
		{
			if( lpfn( ((LPBYTE)lpBlock) + sizeof( BUSY ), lParam ) == 0 )
				break;  // not contunue
		}
	    lpBlock = lpBlock->busy.lpNext;
		lpBlock = (LPBLOCK) ( (DWORD)lpBlock & ( ~(ALLOC_FLAG+BUSY_FLAG) ) );
	}

	LeaveCriticalLock( lpHeap, TRUE );

	return TRUE;
}

/**************************************************
声明:BOOL WINAPI KL_HeapValidate( HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem )

参数:
	hHeap -堆句柄(调用HeapCreate返回的句柄)
	dwFlags – 属性,可以是:
		HEAP_NO_SERIALIZE – 说明当进行堆操作时不必进行互斥
	lpMem – 保留,必须为NULL
返回值:
	假如成功,返回TRUE; 否则返回FALSE
功能描述:
	检查堆是否有效
引用:
	系统API	
************************************************/
#define IS_ZERO_PTR( p ) ( ( (DWORD)p ) < 0x10000 )
BOOL WINAPI KL_HeapValidate( HANDLE hHeap, 
						   DWORD dwFlags,
						   LPCVOID lpMem )
{
	LPHEAP lpHeap = (LPHEAP)hHeap;
    LPBLOCK p, lpPrev; 
	int iRetv = 1;
	if( lpHeap )
	{		
	    EnterCriticalLock( lpHeap, !(dwFlags & HEAP_NO_SERIALIZE) );

		if( lpMem )
		{
			iRetv = IsPtrValid( lpMem, NULL, NULL );
		}
		else 
		{
			
			lpPrev = NULL;
			for ( p = lpHeap->lpFreeList; p; p = p->lpNextFree )
			{
				if( IS_ZERO_PTR( p ) )
				{
					ERRORMSG( 1, ("Invalidate heap freelist ptr:lpHeap=%x,p=0x%x.\r\n", lpHeap, p ) );
					iRetv = 0;
					break;
				}
				else if( p->lpPrevFree != lpPrev )
				{
					ERRORMSG( 1, ("Invalidate heap freelist ptr:lpHeap=%x,p=0x%x,p->lpPrevFree=%x,lpPrev=%x.\r\n", lpHeap, p , p->lpPrevFree, lpPrev ) );
					iRetv = 0;
					break;
				}
				lpPrev = p;   
			}
			
			lpPrev = NULL;
			for ( p = lpHeap->lpFirstBlock; p; p = (LPBLOCK)( (DWORD)p->busy.lpNext & (~(BUSY_FLAG+ALLOC_FLAG) ) ) )
			{
				if( IS_ZERO_PTR( p ) )
				{
					ERRORMSG( 1, ("Invalidate heap freelist ptr:lpHeap=%x,0xp=0x%x.\r\n", lpHeap, p ) );
					iRetv = 0;
					break;
				}			
				else if( p->busy.lpPrev != lpPrev )
				{
					ERRORMSG( 1, ("Invalidate heap busy list, lpHeap=%x,p=0x%x.\r\n", lpHeap, p ) );
					iRetv = 0;
					break;
				}
				lpPrev = p;
				
			}
		}
		LeaveCriticalLock( lpHeap, !(dwFlags & HEAP_NO_SERIALIZE) );
	}
	return iRetv;
}

⌨️ 快捷键说明

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