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

📄 klheap.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
				// 减去已分配的内存大小
				lpHeap->lpbCur += dwCommitSize;
				lpHeap->dwCurUseSize += dwCommitSize;
				lpHeap->dwTotalCommitSize += dwCommitSize;
				*lpdwRealSize = dwCommitSize - uiNewSectionSize;
				//RETAILMSG( 1, ( "GetSystemMem:*lpdwRealSize=%d,dwSize=%d,p=0x%x,lpHeap->lpbCur=%x, ProcID=%x, ThreadID=%x, CPSR=%x.\r\n",*lpdwRealSize, dwSize, p, lpHeap->lpbCur, KL_GetCurrentProcessId(), KL_GetCurrentThreadId(), KL_GetCPSR() ) );
			}
			else
			{
				WARNMSG( DEBUG_GETSYSTEMMEM, ( "error: GetSystemMem: can't to commit enough memory size(%d).\r\n", dwCommitSize ) );
			}
		}
		DEBUGMSG( DEBUG_GETSYSTEMMEM, ( "GetSystemMem:lpHeap=%x,dwTotalSize=%d,ProcessId=%d.\r\n", lpHeap, lpHeap->dwTotalCommitSize, KL_GetCurrentProcessId() ) );
		
		return p;
	}

//#else

	else

#endif
	{   // 用DoAllocPageMem去分配内存
		LPBYTE p = NULL;
		*lpdwRealSize = 0;
		dwSize += sizeof(SECTION);  // 真实的需要分配的内存大小
		
		p = DoAllocPageMem( dwSize, lpdwRealSize, 0 );
		if( p )
		{   // 将其加入堆链表
			Heap_AddToSection( lpHeap, (LPSECTION)p, *lpdwRealSize );
			lpHeap->dwTotalReserveSize  += *lpdwRealSize;
			lpHeap->dwTotalCommitSize  += *lpdwRealSize;


			p = p + sizeof(SECTION);
			*lpdwRealSize -= sizeof(SECTION);

			
		}
		return p;
	}

}

/**************************************************
声明:static BOOL Heap_MemCheck( LPHEAP lpHeap )
参数:
	lpHeap - HEAP 结构指针,指向堆信息
返回值:
	假如成功,返回TRUE; 否则,返回FALSE
功能描述:
	检查堆是否合法

引用: 
	
************************************************/

static BOOL Heap_MemCheck( LPHEAP lpHeap )
{
    LPBLOCK lpBlock, lpFirstBlock;

	// 进入互斥段
	EnterCriticalLock( lpHeap, TRUE ); 

	lpFirstBlock = lpBlock = lpHeap->lpFirstBlock;
	KL_DebugOutString( "........check heap.........\r\n" );
	while( lpBlock )
	{
		if( IS_ALLOC(lpBlock) )//&& !IS_GAP( lpBlock ) )
		{
		    ASSERT_NOTIFY(  0 , (char*)lpBlock + sizeof( BUSY ) );//"memory not free when exit ap!!" );
		}
	    lpBlock = lpBlock->busy.lpNext;// - (ALLOC_FLAG+BUSY_FLAG);
		lpBlock = (LPBLOCK) ( (DWORD)lpBlock & ( ~(ALLOC_FLAG+BUSY_FLAG) ) );
	}

	// 离开互斥段
	LeaveCriticalLock( lpHeap, TRUE );

	return TRUE;
}

/**************************************************
声明:BOOL WINAPI KL_HeapDestroy( HANDLE hHeap )
参数:
	hHeap - 堆句柄(为之前调用KL_HeapCreate所返回的句柄)
返回值:
	假如成功,返回TRUE; 否则,返回FALSE
功能描述:
	破坏堆
引用: 
************************************************/

BOOL WINAPI KL_HeapDestroy( HANDLE hHeap )
{
	LPHEAP lpHeap = (LPHEAP)hHeap;

#ifdef VIRTUAL_MEM

	// 如果系统有MMU管理,则用该段代码

    if( lpHeap->dwOption & HEAP_VIRTUAL_ALLOC )
	{   // // 用VirtualFree去释放内存
		LPSECTION lps, lpNext;

		// 进入互斥段
		EnterCriticalLock( lpHeap, TRUE );//LN:2003-05-13, Add
		
		RETAILMSG( 1, ( "Heap_Release:lpHeap=%x.lpbBase=%x.\r\n", lpHeap, lpHeap->lpbCurReserveBase ) );
		// 释放所有的内存段
		lps = lpHeap->lpSection;
		while( lps )
		{
			lpNext = lps->lpNext;
			KL_VirtualFree( lps, 0, MEM_RELEASE );
			lps = lpNext;
		}
		// 离开互斥段
		LeaveCriticalLock( lpHeap, TRUE );//LN:2003-05-13, Add
		
		return DoHeapDestroy( lpHeap );
		
	}

	else

#endif

	{   // 用DoFreePageMem去释放内存		
		LPSECTION lps, lpNext;
		// 进入互斥段
		EnterCriticalLock( lpHeap, TRUE );
		// 释放所有的内存段
		lps = lpHeap->lpSection;
		while( lps )
		{
			lpNext = lps->lpNext;
			DoFreePageMem( lps, lps->ulLen );
			lps = lpNext;
		}
		// 离开互斥段
		LeaveCriticalLock( lpHeap, TRUE );
		
		return DoHeapDestroy( lpHeap );
	}

}


/**************************************************
声明:void _InsertToFree( LPHEAP lpHeap, LPBLOCK p )
参数:
	lpHeap - HEAP结构指针
	p - 内存块
返回值:
功能描述:
	将一个内存块插入堆空闲链表,以便以后使用
引用: 
************************************************/

static void _InsertToFree( LPHEAP lpHeap, LPBLOCK p )
{
	p->lpPrevFree = 0;
    if ( (p->lpNextFree = lpHeap->lpFreeList) != 0 )
        lpHeap->lpFreeList->lpPrevFree = p;
    lpHeap->lpFreeList = p;
}

/**************************************************
声明:void _RemoveFromFree( LPHEAP lpHeap, LPBLOCK p )
参数:
	lpHeap - HEAP结构指针
	p - 内存块
返回值:
功能描述:
	将一个内存块移出堆空闲链表,以便使用
引用: 
************************************************/
static void _RemoveFromFree( LPHEAP lpHeap, LPBLOCK p )
{
    LPBLOCK f, b;
    f = p->lpNextFree;
    b = p->lpPrevFree;
    if ( b ) 
		b->lpNextFree = f;
    else     
		lpHeap->lpFreeList = f;
    if ( f ) 
		f->lpPrevFree = b;
}

/**************************************************
声明:void * WINAPI KL_HeapAlloc( HANDLE hHeap, DWORD dwFlags, DWORD dwSizeNeeded )
参数:
	hHeap - 堆句柄
	dwFlags - 功能,可以为以下值:
		HEAP_NO_SERIALIZE - 不需要串行化(互斥操作)
	dwSizeNeeded - 需要分配的内存大小
返回值:
	假如成功,返回非NULL的指针; 否则返回NULL
功能描述:
	从堆里分配一个内存快
引用:
	系统API 
************************************************/

#define DEBUG_HEAPALLOC 0
void * WINAPI KL_HeapAlloc( HANDLE hHeap, DWORD dwFlags, DWORD dwSizeNeeded )
{
    LPBLOCK p, x, lpBigBlock;
    DWORD dwBigSize, dwSize;
    DWORD dwRealSize;
	LPHEAP lpHeap = (LPHEAP)hHeap;
	DWORD dwSave = dwSizeNeeded;

    if ( !dwSizeNeeded )
        goto M_RETNULL;

    // 对齐大小
	dwSizeNeeded = ((dwSizeNeeded + ALIGNMASK) & ~ALIGNMASK) + sizeof(BUSY);

    if ( dwSizeNeeded < sizeof(BLOCK) ) 
		dwSizeNeeded = sizeof(BLOCK);

    lpBigBlock = 0;	// 用于记录 > dwSize 的最小的一个空闲快
    dwBigSize = 0;	// 用于记录 lpBigBlock的大小

    //进入互斥段
    EnterCriticalLock( lpHeap, TRUE );//LN:2003-05-13, Add

	DEBUGMSG( DEBUG_HEAPALLOC, ( "+++M(0x%x,lock=%d,dwOption=0x%x)M+++.\r\n", KL_GetCurrentThreadId(), lpHeap->iLockCount, lpHeap->dwOption ) );

    // 查找堆空闲链表-在所有大于dwSizeNeeded的空闲块里得到一块适当的空闲块
    for ( p = lpHeap->lpFreeList; p; p = p->lpNextFree )
    {
	    if ( (dwSize = (char*)p->busy.lpNext - (char*)p) >= dwSizeNeeded )
        {   // 空闲块的尺寸大于需要的尺寸
	        if ( dwSize < dwSizeNeeded + dwSizeNeeded ) 
			{   // 假如该空闲块的尺寸小于需要的尺寸的两倍,符合要求,退出查找
				break;
			}
			// 空闲块的尺寸太大,如果符合条件(是目前得到的空闲块里最小的一块)
			// 将其保存在 lpBigBlock, dwBigSize里
	        if ( !lpBigBlock || dwSize < dwBigSize )
            {
                lpBigBlock = p; 
				dwBigSize = dwSize;
            }
        }
    }
    // 是否已经得到符合条件的空闲块
    if ( p == NULL && (p = lpBigBlock) == NULL )
    {   //没有,需要从系统空闲内存去分配大的内存,dwRealSize用于保存实际得到的内存块大小

		p = GetSystemMem( lpHeap, dwSizeNeeded+sizeof(BUSY), (DWORD*)&dwRealSize );

	    if ( p == NULL )
        {  // 无法从系统分配内存,退出
			DEBUGMSG( DEBUG_HEAPALLOC, ( "---M(0x%x)M---.\r\n", KL_GetCurrentThreadId() ) );
			LeaveCriticalLock( lpHeap, TRUE );
	        goto M_RETNULL;
        }

		ASSERT( dwRealSize >= dwSizeNeeded+sizeof(BUSY) );

	    dwRealSize &= ~ALIGNMASK;

	    if ( lpHeap->lpLastBlock &&
	         (char*)p == ((char*)lpHeap->lpLastBlock + sizeof(BUSY)) )
        {   // 新的内存段与之前所分配的内存段是连续的,我们将其组合为一个大段

	        p = lpHeap->lpLastBlock;
	        dwRealSize += sizeof(BUSY);
	        /********************************************************
		    Check if previous block is free and combine it now.
	        ********************************************************/
	        // 如果前一个块是空闲的,则将它与新的连接在一起
			if ( (x = p->busy.lpPrev) != 0 && !IS_BUSY(x) )
            {
		        _RemoveFromFree( lpHeap, x );  // 从空闲链表移出
		        dwRealSize += (char*)p - (char*)x;
		        p = x;
            }
        }
    	else
        {
	        if ( lpHeap->lpLastBlock )
            {
		        p->busy.lpPrev = lpHeap->lpLastBlock;
		        lpHeap->lpLastBlock->busy.lpNext = (LPBLOCK)((char*)p+BUSY_FLAG);
            }
	        else
            {
		        p->busy.lpPrev = NULL;
		        lpHeap->lpFirstBlock = p;
            }
        }

		// 保留一个最小的BLOCK结构,用于记录该内存段的结束

	    p->busy.lpNext = lpHeap->lpLastBlock =
	        (LPBLOCK)((char*)p + dwRealSize - sizeof(BUSY));
	    lpHeap->lpLastBlock->busy.lpPrev = p;
		lpHeap->lpLastBlock->busy.lpNext = (LPBLOCK)(BUSY_FLAG);
        // 将新的段插入空闲链表
	    _InsertToFree( lpHeap, p);
    }
    // p 指向空闲块
    if ( (char*)p->busy.lpNext-(char*)p-dwSizeNeeded > sizeof(BLOCK) )
    {
		// 如果p指向的空闲块较大,则从p指向的空闲块分割族够的内存块,并将剩下的放入空闲链表

	    x = (LPBLOCK)((char*)p + dwSizeNeeded);
	    p->busy.lpNext->busy.lpPrev = x;
	    x->busy.lpPrev = p;
	    x->busy.lpNext = p->busy.lpNext;
	    p->busy.lpNext = (LPBLOCK)((char*)x + BUSY_FLAG + ALLOC_FLAG );
	    _RemoveFromFree( lpHeap, p );
	    _InsertToFree( lpHeap, x );
    }
    else
    {   //将p从空闲链表移出
	    _RemoveFromFree( lpHeap, p );
	    p->busy.lpNext = (LPBLOCK)((char*)p->busy.lpNext+BUSY_FLAG +ALLOC_FLAG);
    }

	//离开互斥段
	DEBUGMSG( DEBUG_HEAPALLOC, ( "---M(0x%x)M---.\r\n", KL_GetCurrentThreadId() ) );
	LeaveCriticalLock( lpHeap, TRUE );
    
	if( dwFlags & HEAP_ZERO_MEMORY )
	{
		memset( (char*)p + sizeof(BUSY), 0, dwSave );
	}

    return (char*)p + sizeof(BUSY);
M_RETNULL:
	KL_SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    WARNMSG( DEBUG_HEAPALLOC, ( TEXT("error HeapAlloc: Not enough memory.!\r\n") ) );
    return NULL;
}

/**************************************************
声明:BOOL IsPtrValid( void FAR * lpvUsed )
参数:
	lpHeap - 堆句柄指针
	lpvUsed - 需要检验的指针(已分配的内存地址)

⌨️ 快捷键说明

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