Alexandre Julliard : ntdll: Convert the subheap list to a standard list.
Alexandre Julliard
julliard at winehq.org
Tue Oct 2 06:52:37 CDT 2007
Module: wine
Branch: master
Commit: 80a6bb1d8ba7ce34f961f31f8e42278840db7406
URL: http://source.winehq.org/git/wine.git/?a=commit;h=80a6bb1d8ba7ce34f961f31f8e42278840db7406
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Oct 1 15:31:14 2007 +0200
ntdll: Convert the subheap list to a standard list.
---
dlls/ntdll/heap.c | 72 +++++++++++++++++++++++-----------------------------
1 files changed, 32 insertions(+), 40 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index a0691ba..dbe9b77 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -109,7 +109,7 @@ typedef struct tagSUBHEAP
SIZE_T size; /* Size of the whole sub-heap */
SIZE_T commitSize; /* Committed size of the sub-heap */
DWORD headerSize; /* Size of the heap header */
- struct tagSUBHEAP *next; /* Next sub-heap */
+ struct list entry; /* Entry in sub-heap list */
struct tagHEAP *heap; /* Main heap structure */
DWORD magic; /* Magic number */
} SUBHEAP;
@@ -120,6 +120,7 @@ typedef struct tagHEAP
{
SUBHEAP subheap; /* First sub-heap */
struct list entry; /* Entry in process heap list */
+ struct list subheap_list; /* Sub-heap list */
RTL_CRITICAL_SECTION critSection; /* Critical section for serialization */
FREE_LIST_ENTRY freeList[HEAP_NB_FREE_LISTS]; /* Free lists */
DWORD flags; /* Heap flags */
@@ -226,14 +227,8 @@ static void HEAP_Dump( HEAP *heap )
char *ptr;
DPRINTF( "Heap: %p\n", heap );
- DPRINTF( "Next: %p Sub-heaps: %p",
- LIST_ENTRY( heap->entry.next, HEAP, entry ), &heap->subheap );
- subheap = &heap->subheap;
- while (subheap->next)
- {
- DPRINTF( " -> %p", subheap->next );
- subheap = subheap->next;
- }
+ DPRINTF( "Next: %p Sub-heaps:", LIST_ENTRY( heap->entry.next, HEAP, entry ) );
+ LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) DPRINTF( " %p", subheap );
DPRINTF( "\nFree lists:\n Block Stat Size Id\n" );
for (i = 0; i < HEAP_NB_FREE_LISTS; i++)
@@ -242,8 +237,7 @@ static void HEAP_Dump( HEAP *heap )
LIST_ENTRY( heap->freeList[i].arena.entry.prev, ARENA_FREE, entry ),
LIST_ENTRY( heap->freeList[i].arena.entry.next, ARENA_FREE, entry ));
- subheap = &heap->subheap;
- while (subheap)
+ LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry )
{
SIZE_T freeSize = 0, usedSize = 0, arenaSize = subheap->headerSize;
DPRINTF( "\n\nSub-heap %p: base=%p size=%08lx committed=%08lx\n",
@@ -285,7 +279,6 @@ static void HEAP_Dump( HEAP *heap )
DPRINTF( "\nTotal: Size=%08lx Committed=%08lx Free=%08lx Used=%08lx Arenas=%08lx (%ld%%)\n\n",
subheap->size, subheap->commitSize, freeSize, usedSize,
arenaSize, (arenaSize * 100) / subheap->size );
- subheap = subheap->next;
}
}
@@ -390,16 +383,13 @@ static inline void HEAP_InsertFreeBlock( HEAP *heap, ARENA_FREE *pArena, BOOL la
*/
static SUBHEAP *HEAP_FindSubHeap(
const HEAP *heap, /* [in] Heap pointer */
- LPCVOID ptr /* [in] Address */
-) {
- const SUBHEAP *sub = &heap->subheap;
- while (sub)
- {
+ LPCVOID ptr ) /* [in] Address */
+{
+ SUBHEAP *sub;
+ LIST_FOR_EACH_ENTRY( sub, &heap->subheap_list, SUBHEAP, entry )
if (((const char *)ptr >= (const char *)sub->base) &&
((const char *)ptr < (const char *)sub->base + sub->size - sizeof(ARENA_INUSE)))
- return (SUBHEAP *)sub;
- sub = sub->next;
- }
+ return sub;
return NULL;
}
@@ -548,12 +538,10 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
{
SIZE_T size = 0;
void *addr = subheap->base;
- SUBHEAP *pPrev = &subheap->heap->subheap;
/* Remove the free block from the list */
list_remove( &pFree->entry );
/* Remove the subheap from the list */
- while (pPrev && (pPrev->next != subheap)) pPrev = pPrev->next;
- if (pPrev) pPrev->next = subheap->next;
+ list_remove( &subheap->entry );
/* Free the memory */
subheap->magic = 0;
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
@@ -621,8 +609,7 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
subheap->commitSize = commitSize;
subheap->magic = SUBHEAP_MAGIC;
subheap->headerSize = ROUND_SIZE( sizeof(SUBHEAP) );
- subheap->next = heap->subheap.next;
- heap->subheap.next = subheap;
+ list_add_head( &heap->subheap_list, &subheap->entry );
}
else
{
@@ -631,6 +618,7 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
heap = (HEAP *)address;
heap->flags = flags;
heap->magic = HEAP_MAGIC;
+ list_init( &heap->subheap_list );
subheap = &heap->subheap;
subheap->base = address;
@@ -639,7 +627,7 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
subheap->commitSize = commitSize;
subheap->magic = SUBHEAP_MAGIC;
subheap->headerSize = ROUND_SIZE( sizeof(HEAP) );
- subheap->next = NULL;
+ list_add_head( &heap->subheap_list, &subheap->entry );
/* Build the free lists */
@@ -1035,8 +1023,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
return ret;
}
- subheap = &heapPtr->subheap;
- while (subheap && ret)
+ LIST_FOR_EACH_ENTRY( subheap, &heapPtr->subheap_list, SUBHEAP, entry )
{
char *ptr = (char *)subheap->base + subheap->headerSize;
while (ptr < (char *)subheap->base + subheap->size)
@@ -1058,7 +1045,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
ptr += sizeof(ARENA_INUSE) + (*(DWORD *)ptr & ARENA_SIZE_MASK);
}
}
- subheap = subheap->next;
+ if (!ret) break;
}
if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
@@ -1131,7 +1118,9 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c
HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
{
HEAP *heapPtr = HEAP_GetPtr( heap );
- SUBHEAP *subheap;
+ SUBHEAP *subheap, *next;
+ SIZE_T size;
+ void *addr;
TRACE("%p\n", heap );
if (!heapPtr) return heap;
@@ -1145,15 +1134,18 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
heapPtr->critSection.DebugInfo->Spare[0] = 0;
RtlDeleteCriticalSection( &heapPtr->critSection );
- subheap = &heapPtr->subheap;
- while (subheap)
+
+ LIST_FOR_EACH_ENTRY_SAFE( subheap, next, &heapPtr->subheap_list, SUBHEAP, entry )
{
- SUBHEAP *next = subheap->next;
- SIZE_T size = 0;
- void *addr = subheap->base;
+ if (subheap == &heapPtr->subheap) continue; /* do this one last */
+ list_remove( &subheap->entry );
+ size = 0;
+ addr = subheap->base;
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
- subheap = next;
}
+ size = 0;
+ addr = heapPtr->subheap.base;
+ NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
return 0;
}
@@ -1617,8 +1609,7 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
else
{
ptr = entry->lpData;
- sub = &heapPtr->subheap;
- while (sub)
+ LIST_FOR_EACH_ENTRY( sub, &heapPtr->subheap_list, SUBHEAP, entry )
{
if (((char *)ptr >= (char *)sub->base) &&
((char *)ptr < (char *)sub->base + sub->size))
@@ -1626,7 +1617,6 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
currentheap = sub;
break;
}
- sub = sub->next;
region_index++;
}
if (currentheap == NULL)
@@ -1651,12 +1641,14 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
if (ptr > (char *)currentheap->base + currentheap->size - 1)
{ /* proceed with next subheap */
- if (!(currentheap = currentheap->next))
+ struct list *next = list_next( &heapPtr->subheap_list, ¤theap->entry );
+ if (!next)
{ /* successfully finished */
TRACE("end reached.\n");
ret = STATUS_NO_MORE_ENTRIES;
goto HW_end;
}
+ currentheap = LIST_ENTRY( next, SUBHEAP, entry );
ptr = (char *)currentheap->base + currentheap->headerSize;
}
}
More information about the wine-cvs
mailing list