现在的位置: 首页 > 综合 > 正文

代码分析:Wine HeapFree 函数

2013年08月04日 ⁄ 综合 ⁄ 共 1277字 ⁄ 字号 评论关闭

 HeapFree

代码位置和生命及参考资料,请参考上一篇:)

HeapFree -> RtlFreeHeap
这个函数直接调用的就是RtlFrreHeap,前面依然是检查一下参数,判断一下标志位。

pInUse = (ARENA_INUSE *)ptr - 1;
if (!(subheap = HEAP_FindSubHeap( heapPtr, pInUse ))) goto error;
然后用当前INUSE的块的位置,调用HEAP_FindSubHeap函数找到当前INUSE的前面一个INUSE块的子堆的指针,并检查这个块是不是一个有效的块。

然后调用HEAP_MakeInUseBlockFree()函数,这个函数的作用是把InUse的block变为空闲的。下面我们看看这个函数:
HeapFree -> RtlFreeHeap -> HEAP_MakeInUseBlockFree
if (pArena->size & ARENA_FLAG_PREV_FREE)
首先检查要释放的空间的大小和前一块block是否也是空闲的,若前一块也是空闲的,就把前一块空闲块和这个释放的块合并起来做为一个更大的空闲块。若否,仅把当前块转为空闲块。

接着调用HEAP_CreateFreeBlock把这个原本InUse的块转换成Free的块,其实就是把结构变变,然后把标志位制为free,并且挂入空闲队列。

果刚才编程free的这个block是最后不是最后一个block,那么回到RtlFreeHeap继续执行,如果刚才转换成Free的block是某个
子堆的最后一个block,那就继续看看这个子堆不是第一个subheap并且是空的,那么整个subheap也一起释放掉

代码: 全选
545     if (((char *)pFree == (char *)subheap->base + subheap->headerSize) &&
546         (subheap != &subheap->heap->subheap))
547     {
548         SIZE_T size = 0;
549         void *addr = subheap->base;
550         /* Remove the free block from the list */
551         list_remove( &pFree->entry );
552         /* Remove the subheap from the list */
553         list_remove( &subheap->entry );
554         /* Free the memory */
555         subheap->magic = 0;
556         NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
557         return;
558     }

然后返回到RtlFreeHeap(),若刚才设置了share标志位,进入了临界区,则退出临界区,返回TRUE,表示释放成功。
若刚才中途出错,则 跳转到goto的位置,撤出临界区和返回错误码,并且返回 FALSE.

抱歉!评论已关闭.