ntdll: Split RtlAllocateHeap to a separate heap_allocate helper.
Factoring out locking and status handling. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
80a1155ca8
commit
dadb1fa72f
|
@ -411,6 +411,7 @@ static void test_HeapCreate(void)
|
||||||
/* shrinking a very large block decommits pages and fail to grow in place */
|
/* shrinking a very large block decommits pages and fail to grow in place */
|
||||||
ptr1 = HeapReAlloc( heap, HEAP_REALLOC_IN_PLACE_ONLY, ptr, alloc_size * 3 / 2 );
|
ptr1 = HeapReAlloc( heap, HEAP_REALLOC_IN_PLACE_ONLY, ptr, alloc_size * 3 / 2 );
|
||||||
ok( ptr1 == ptr, "HeapReAlloc HEAP_REALLOC_IN_PLACE_ONLY failed, error %lu\n", GetLastError() );
|
ok( ptr1 == ptr, "HeapReAlloc HEAP_REALLOC_IN_PLACE_ONLY failed, error %lu\n", GetLastError() );
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
ptr1 = HeapReAlloc( heap, HEAP_REALLOC_IN_PLACE_ONLY, ptr, 2 * alloc_size );
|
ptr1 = HeapReAlloc( heap, HEAP_REALLOC_IN_PLACE_ONLY, ptr, 2 * alloc_size );
|
||||||
todo_wine
|
todo_wine
|
||||||
ok( ptr1 != ptr, "HeapReAlloc HEAP_REALLOC_IN_PLACE_ONLY succeeded\n" );
|
ok( ptr1 != ptr, "HeapReAlloc HEAP_REALLOC_IN_PLACE_ONLY succeeded\n" );
|
||||||
|
@ -482,7 +483,6 @@ static void test_HeapCreate(void)
|
||||||
SetLastError( 0xdeadbeef );
|
SetLastError( 0xdeadbeef );
|
||||||
ptr1 = HeapAlloc( heap, 0, 4 * alloc_size );
|
ptr1 = HeapAlloc( heap, 0, 4 * alloc_size );
|
||||||
ok( !ptr1, "HeapAlloc succeeded\n" );
|
ok( !ptr1, "HeapAlloc succeeded\n" );
|
||||||
todo_wine
|
|
||||||
ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() );
|
ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() );
|
||||||
ret = HeapFree( heap, 0, ptr1 );
|
ret = HeapFree( heap, 0, ptr1 );
|
||||||
ok( ret, "HeapFree failed, error %lu\n", GetLastError() );
|
ok( ret, "HeapFree failed, error %lu\n", GetLastError() );
|
||||||
|
|
|
@ -349,6 +349,12 @@ static void heap_unlock( HEAP *heap, ULONG flags )
|
||||||
RtlLeaveCriticalSection( &heap->cs );
|
RtlLeaveCriticalSection( &heap->cs );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void heap_set_status( const HEAP *heap, ULONG flags, NTSTATUS status )
|
||||||
|
{
|
||||||
|
if (status == STATUS_NO_MEMORY && (flags & HEAP_GENERATE_EXCEPTIONS)) RtlRaiseStatus( status );
|
||||||
|
if (status) RtlSetLastWin32ErrorAndNtStatusFromNtStatus( status );
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* HEAP_Dump
|
* HEAP_Dump
|
||||||
*/
|
*/
|
||||||
|
@ -1648,66 +1654,27 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS heap_allocate( HEAP *heap, ULONG flags, SIZE_T size, void **ret )
|
||||||
/***********************************************************************
|
|
||||||
* RtlAllocateHeap (NTDLL.@)
|
|
||||||
*
|
|
||||||
* Allocate a memory block from a Heap.
|
|
||||||
*
|
|
||||||
* PARAMS
|
|
||||||
* heap [I] Heap to allocate block from
|
|
||||||
* flags [I] HEAP_ flags from "winnt.h"
|
|
||||||
* size [I] Size of the memory block to allocate
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Success: A pointer to the newly allocated block
|
|
||||||
* Failure: NULL.
|
|
||||||
*
|
|
||||||
* NOTES
|
|
||||||
* This call does not SetLastError().
|
|
||||||
*/
|
|
||||||
void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
|
|
||||||
{
|
{
|
||||||
ARENA_FREE *pArena;
|
ARENA_FREE *pArena;
|
||||||
ARENA_INUSE *pInUse;
|
ARENA_INUSE *pInUse;
|
||||||
SUBHEAP *subheap;
|
SUBHEAP *subheap;
|
||||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
|
||||||
SIZE_T rounded_size;
|
SIZE_T rounded_size;
|
||||||
|
|
||||||
/* Validate the parameters */
|
|
||||||
|
|
||||||
if (!heapPtr) return NULL;
|
|
||||||
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
|
|
||||||
flags |= heapPtr->flags;
|
|
||||||
rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags );
|
rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags );
|
||||||
if (rounded_size < size) /* overflow */
|
|
||||||
{
|
|
||||||
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;
|
|
||||||
|
|
||||||
heap_lock( heapPtr, flags );
|
if (rounded_size < size) return STATUS_NO_MEMORY; /* overflow */
|
||||||
|
if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;
|
||||||
|
|
||||||
if (rounded_size >= HEAP_MIN_LARGE_BLOCK_SIZE && (flags & HEAP_GROWABLE))
|
if (rounded_size >= HEAP_MIN_LARGE_BLOCK_SIZE && (flags & HEAP_GROWABLE))
|
||||||
{
|
{
|
||||||
void *ret = allocate_large_block( heap, flags, size );
|
if (!(*ret = allocate_large_block( heap, flags, size ))) return STATUS_NO_MEMORY;
|
||||||
heap_unlock( heapPtr, flags );
|
return STATUS_SUCCESS;
|
||||||
if (!ret && (flags & HEAP_GENERATE_EXCEPTIONS)) RtlRaiseStatus( STATUS_NO_MEMORY );
|
|
||||||
TRACE("(%p,%08x,%08lx): returning %p\n", heap, flags, size, ret );
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locate a suitable free block */
|
/* Locate a suitable free block */
|
||||||
|
|
||||||
if (!(pArena = HEAP_FindFreeBlock( heapPtr, rounded_size, &subheap )))
|
if (!(pArena = HEAP_FindFreeBlock( heap, rounded_size, &subheap ))) return STATUS_NO_MEMORY;
|
||||||
{
|
|
||||||
TRACE("(%p,%08x,%08lx): returning NULL\n",
|
|
||||||
heap, flags, size );
|
|
||||||
heap_unlock( heapPtr, flags );
|
|
||||||
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the arena from the free list */
|
/* Remove the arena from the free list */
|
||||||
|
|
||||||
|
@ -1730,10 +1697,31 @@ void * WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_
|
||||||
notify_alloc( pInUse + 1, size, flags & HEAP_ZERO_MEMORY );
|
notify_alloc( pInUse + 1, size, flags & HEAP_ZERO_MEMORY );
|
||||||
initialize_block( pInUse + 1, size, pInUse->unused_bytes, flags );
|
initialize_block( pInUse + 1, size, pInUse->unused_bytes, flags );
|
||||||
|
|
||||||
heap_unlock( heapPtr, flags );
|
*ret = pInUse + 1;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("(%p,%08x,%08lx): returning %p\n", heap, flags, size, pInUse + 1 );
|
/***********************************************************************
|
||||||
return pInUse + 1;
|
* RtlAllocateHeap (NTDLL.@)
|
||||||
|
*/
|
||||||
|
void *WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
|
||||||
|
{
|
||||||
|
void *ptr = NULL;
|
||||||
|
NTSTATUS status;
|
||||||
|
HEAP *heapPtr;
|
||||||
|
|
||||||
|
if (!(heapPtr = HEAP_GetPtr( heap )))
|
||||||
|
status = STATUS_INVALID_HANDLE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
heap_lock( heapPtr, flags );
|
||||||
|
status = heap_allocate( heapPtr, heap_get_flags( heapPtr, flags ), size, &ptr );
|
||||||
|
heap_unlock( heapPtr, flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE( "heap %p, flags %#x, size %#Ix, return %p, status %#x.\n", heap, flags, size, ptr, status );
|
||||||
|
heap_set_status( heapPtr, flags, status );
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue