From: Paul Gofman <pgofman@codeweavers.com> --- dlls/kernel32/tests/heap.c | 75 +++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 6722bc6af28..4795c60e9ea 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -38,6 +38,8 @@ #define HEAP_VALIDATE_ALL 0x20000000 #define HEAP_VALIDATE_PARAMS 0x40000000 +#define REGION_ALIGN 0x10000 +#define INITIAL_COMMIT_ALIGN (0x400 * sizeof(void *)) #define BLOCK_ALIGN (2 * sizeof(void *) - 1) #define ALIGN_BLOCK_SIZE(x) (((x) + BLOCK_ALIGN) & ~BLOCK_ALIGN) @@ -573,8 +575,7 @@ static void test_HeapCreate(void) ok( entries[0].cbData <= 0x1000 /* sizeof(*heap) */, "got cbData %#lx\n", entries[0].cbData ); ok( entries[0].cbOverhead == 0, "got cbOverhead %#x\n", entries[0].cbOverhead ); ok( entries[0].iRegionIndex == 0, "got iRegionIndex %d\n", entries[0].iRegionIndex ); - todo_wine - ok( entries[0].Region.dwCommittedSize == 0x400 * sizeof(void *), + todo_wine ok( entries[0].Region.dwCommittedSize == 0x400 * sizeof(void *), "got Region.dwCommittedSize %#lx\n", entries[0].Region.dwCommittedSize ); ok( entries[0].Region.dwUnCommittedSize == 0x10000 - entries[0].Region.dwCommittedSize || entries[0].Region.dwUnCommittedSize == 0x10000 * sizeof(void *) - entries[0].Region.dwCommittedSize /* win7 */, @@ -749,6 +750,9 @@ static void test_HeapCreate(void) while ((ret = HeapWalk( heap, &entry ))) entries[count++] = entry; ok( GetLastError() == ERROR_NO_MORE_ITEMS, "got error %lu\n", GetLastError() ); ok( count == 4, "got count %lu\n", count ); + todo_wine ok( entries->Region.dwCommittedSize == INITIAL_COMMIT_ALIGN, "got %#lx.\n", entries->Region.dwCommittedSize ); + ok( entries->Region.dwUnCommittedSize == REGION_ALIGN - entries->Region.dwCommittedSize, "got %#lx.\n", + entries->Region.dwUnCommittedSize ); ok( !memcmp( entries + 16, entries, 1 * sizeof(entry) ), "entries differ\n" ); ok( memcmp( entries + 17, entries + 2, 2 * sizeof(entry) ), "entries differ\n" ); @@ -3685,12 +3689,13 @@ static void test_GlobalMemoryStatus(void) #undef IS_WITHIN_RANGE } -static void get_valloc_info( void *mem, char **base, SIZE_T *alloc_size ) +static void get_valloc_info( void *mem, char **base, SIZE_T *alloc_size, SIZE_T *commit_size ) { MEMORY_BASIC_INFORMATION info, info2; SIZE_T size; char *p; + *commit_size = 0; size = VirtualQuery( mem, &info, sizeof(info) ); ok( size == sizeof(info), "got %Iu.\n", size ); @@ -3703,6 +3708,7 @@ static void get_valloc_info( void *mem, char **base, SIZE_T *alloc_size ) if (info2.AllocationBase != info.AllocationBase) break; ok( info2.State == MEM_RESERVE || info2.State == MEM_COMMIT, "got %#lx.\n", info2.State ); + if (info2.State == MEM_COMMIT) *commit_size += info2.RegionSize; p += info2.RegionSize; } @@ -3710,32 +3716,41 @@ static void get_valloc_info( void *mem, char **base, SIZE_T *alloc_size ) *alloc_size = p - *base; } -static void test_heap_size( SIZE_T initial_size ) +static void test_heap_size( SIZE_T initial_commit_size ) { - static const SIZE_T default_heap_size = 0x10000, init_grow_size = 0x100000, max_grow_size = 0xfd0000; + static const SIZE_T init_grow_size = 0x100000, max_grow_size = 0xfd0000, test_alloc_size = 0x60000; BOOL initial_subheap = TRUE, max_size_reached = FALSE; - SIZE_T alloc_size, current_subheap_size; + SIZE_T alloc_size, committed_size, current_subheap_size, expected, commit_size, initial_committed_size; char *base, *current_base; + BOOL subheap_changed; unsigned int i; HANDLE heap; void *p; - winetest_push_context( "init size %#Ix", initial_size ); - heap = HeapCreate( HEAP_NO_SERIALIZE, initial_size, 0 ); - get_valloc_info( heap, ¤t_base, &alloc_size ); + winetest_push_context( "init size %#Ix", initial_commit_size ); + heap = HeapCreate( HEAP_NO_SERIALIZE, initial_commit_size, 0 ); + get_valloc_info( heap, ¤t_base, &alloc_size, &committed_size ); + + commit_size = ROUND_SIZE( initial_commit_size, INITIAL_COMMIT_ALIGN - 1 ); + expected = ROUND_SIZE( commit_size + 1, REGION_ALIGN - 1 ); - ok( alloc_size == initial_size + default_heap_size || broken( (initial_size && alloc_size == initial_size) - || (!initial_size && (alloc_size == default_heap_size * sizeof(void*))) ) /* Win7 */, - "got %#Ix.\n", alloc_size ); + todo_wine_if( expected != initial_commit_size + REGION_ALIGN + && !(initial_commit_size > REGION_ALIGN - INITIAL_COMMIT_ALIGN && initial_commit_size < REGION_ALIGN)) + ok( alloc_size == expected, "got %#Ix, expected %#Ix.\n", alloc_size, expected ); + expected = max( commit_size, INITIAL_COMMIT_ALIGN ); + todo_wine_if( (!initial_commit_size || (initial_commit_size & (REGION_ALIGN - 1))) + && !(initial_commit_size > REGION_ALIGN - INITIAL_COMMIT_ALIGN && initial_commit_size < REGION_ALIGN)) + ok( committed_size == expected, "got commit size %#Ix, expected %#Ix.\n", committed_size, expected ); current_subheap_size = alloc_size; + initial_committed_size = committed_size; + commit_size = 0; for (i = 0; i < 100; ++i) { - winetest_push_context( "i %u, current_subheap_size %#Ix", i, current_subheap_size ); - p = HeapAlloc( heap, 0, 0x60000 ); - get_valloc_info( p, &base, &alloc_size ); - if (base != current_base) + p = HeapAlloc( heap, 0, test_alloc_size ); + get_valloc_info( p, &base, &alloc_size, &committed_size ); + if ((subheap_changed = (base != current_base))) { current_base = base; if (initial_subheap) @@ -3749,8 +3764,18 @@ static void test_heap_size( SIZE_T initial_size ) if (current_subheap_size == max_grow_size) max_size_reached = TRUE; } + commit_size = 0x1000; + initial_committed_size = 0; } + + winetest_push_context( "i %u, current_subheap_size %#Ix, subheap_changed %d", i, current_subheap_size, + subheap_changed ); + commit_size += test_alloc_size + 0x1000; ok( alloc_size == current_subheap_size, "got %#Ix.\n", alloc_size ); + expected = max( initial_committed_size, commit_size ); + todo_wine_if(commit_size != 0x5b0000 && expected != initial_commit_size) + ok( committed_size == expected, "got %#Ix, expected %#Ix, commit_size %#Ix, initial_committed_size %#Ix. p %p.\n", + committed_size, expected, commit_size, initial_committed_size, p ); winetest_pop_context(); } ok( max_size_reached, "Did not reach maximum subheap size.\n" ); @@ -3762,10 +3787,24 @@ static void test_heap_size( SIZE_T initial_size ) static void test_heap_sizes(void) { unsigned int i; - SIZE_T size, round_size = 0x400 * sizeof(void*); + SIZE_T size, commit_size, round_size = 0x400 * sizeof(void*); char *base; test_heap_size( 0 ); + test_heap_size( 1 ); + test_heap_size( 0x100 ); + test_heap_size( 0xf00 ); + test_heap_size( 0xfff ); + test_heap_size( 0x1000 ); + test_heap_size( 0xe000 ); + test_heap_size( 0xe001 ); + test_heap_size( 0xf000 ); + test_heap_size( 0xf001 ); + test_heap_size( 0xffff ); + test_heap_size( 0x10000 ); + test_heap_size( 0x20fff ); + test_heap_size( 0x30000 ); + test_heap_size( 0x30001 ); test_heap_size( 0x80000 ); test_heap_size( 0x150000 ); @@ -3773,7 +3812,7 @@ static void test_heap_sizes(void) { HANDLE heap = HeapCreate( 0, i * 0x100, i * 0x100 ); ok( heap != NULL, "%x: creation failed\n", i * 0x100 ); - get_valloc_info( heap, &base, &size ); + get_valloc_info( heap, &base, &size, &commit_size ); ok( size == ((i * 0x100 + round_size - 1) & ~(round_size - 1)), "%x: wrong size %Ix\n", i * 0x100, size ); HeapDestroy( heap ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9752