嵌入式操作系统
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

6.4.2 堆的销毁

堆的销毁分两种情况:一种情况是销毁单个堆;另外一种情况是销毁当前线程的所有堆。其中,第二种情况一般在线程结束的时候,由线程结束收尾函数(KernelThread Wrapper函数)调用,用来释放当前线程尚未释放的所有堆对象。对于第一种情况,一般是由应用程序编写者调用的,用来撤销自己创建的堆。

其中,销毁当前线程所有堆(DestroyAllHeap)的实现,也是调用了销毁单个堆的实现算法,因此,在此只简单介绍销毁单个堆的实现代码。对于堆的撤销操作,比较简单,所需要完成的,只是内存资源的回收而已。目前的实现中,在DestroyHeap的实现中,完成下列动作:

① 从当前线程的堆链表中,删除要销毁的堆对象(该对象作为函数的参数传递);

② 释放该堆对象申请的所有虚拟区域;

③ 然后把虚拟区域链表所占用内存释放,即虚拟区域节点占用内存;

④ 最后,释放堆对象本身。

代码如下。

static VOID DestroyHeap(__HEAP_OBJECT* lpHeapObject)
{
    __VIRTUAL_AREA_NODE*      lpVirtualArea=NULL;
    __VIRTUAL_AREA_NODE*      lpVirtualTmp =NULL;
    LPVOID                  lpVirtualAddr=NULL;
    DWORD                   dwFlags     =0L;
    if(NULL==lpHeapObject)  //Parameter check.
        return;
    if(lpHeapObject==lpHeapObject->lpNext)  //Only one heap object
                                            //in current thread.
    {
        __ENTER_CRITICAL_SECTION(NULL,dwFlags);
        lpHeapObject->lpKernelThread->lpHeapObject=NULL;
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
    }
    else  //Delete itself from the kernel thread's heap list.
    {
        __ENTER_CRITICAL_SECTION(NULL,dwFlags);
        if(lpHeapObject->lpKernelThread->lpHeapObject==lpHeap Object)
        {
            lpHeapObject->lpKernelThread->lpHeapObject=(LPVOID) lpHeap
Object->lpNext;
        }
        __LEAVE_CRITICAL_SECTION(NULL,dwFlags);
        lpHeapObject->lpPrev->lpNext=lpHeapObject->lpNext;
        lpHeapObject->lpNext->lpPrev=lpHeapObject->lpPrev;
    }
    lpVirtualArea=lpHeapObject->lpVirtualArea;
    while(lpVirtualArea)
    {
        lpVirtualTmp=lpVirtualArea;
        lpVirtualArea=lpVirtualArea->lpNext;
        RELEASE_VIRTUAL_AREA(lpVirtualTmp->lpStartAddress);
//Release the virtual area.
        RELEASE_KERNEL_MEMORY((LPVOID)lpVirtualTmp);
    }
    //
    //Now,should release the heap object itself.
    //
    RELEASE_KERNEL_MEMORY((LPVOID)lpHeapObject);
    return;
    }