mirror of
https://github.com/decompals/wibo.git
synced 2025-12-11 14:41:58 +00:00
110 lines
3.2 KiB
C
110 lines
3.2 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <windows.h>
|
|
|
|
#include "test_assert.h"
|
|
|
|
const SIZE_T LARGE_BLOCK_SIZE = 64ULL * 1024ULL * 1024ULL; // 64 MiB
|
|
const SIZE_T SMALL_BLOCK_SIZE = 64ULL * 1024ULL; // 64 KiB
|
|
|
|
static void test_basics() {
|
|
HANDLE processHeap = GetProcessHeap();
|
|
TEST_CHECK(processHeap != NULL);
|
|
|
|
uint8_t *block = (uint8_t *)HeapAlloc(processHeap, HEAP_ZERO_MEMORY, 32);
|
|
TEST_CHECK(block != NULL);
|
|
for (size_t i = 0; i < 32; i++) {
|
|
TEST_CHECK(block[i] == 0);
|
|
}
|
|
|
|
SIZE_T blockSize = HeapSize(processHeap, 0, block);
|
|
TEST_CHECK(blockSize >= 32);
|
|
|
|
memset(block, 0xAA, 16);
|
|
uint8_t *grown = (uint8_t *)HeapReAlloc(processHeap, HEAP_ZERO_MEMORY, block, 64);
|
|
TEST_CHECK(grown != NULL);
|
|
for (size_t i = 0; i < 16; i++) {
|
|
TEST_CHECK(grown[i] == 0xAA);
|
|
}
|
|
for (size_t i = 16; i < 64; i++) {
|
|
TEST_CHECK(grown[i] == 0);
|
|
}
|
|
|
|
SetLastError(0);
|
|
void *inPlace = HeapReAlloc(processHeap, HEAP_REALLOC_IN_PLACE_ONLY, grown, 2048);
|
|
TEST_CHECK(inPlace == NULL);
|
|
TEST_CHECK_EQ(ERROR_NOT_ENOUGH_MEMORY, GetLastError());
|
|
|
|
TEST_CHECK(HeapFree(processHeap, 0, grown));
|
|
|
|
HANDLE privateHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
|
|
TEST_CHECK(privateHeap != NULL);
|
|
|
|
void *privateBlock = HeapAlloc(privateHeap, 0, 8);
|
|
TEST_CHECK(privateBlock != NULL);
|
|
|
|
SetLastError(0);
|
|
// Disabled temporarily; no good way to detect individual heap allocations
|
|
// in mimalloc currently. See https://github.com/microsoft/mimalloc/issues/298
|
|
#if 0
|
|
TEST_CHECK(!HeapFree(processHeap, 0, privateBlock));
|
|
TEST_CHECK_EQ(ERROR_INVALID_PARAMETER, GetLastError());
|
|
#endif
|
|
|
|
TEST_CHECK(HeapFree(privateHeap, 0, privateBlock));
|
|
TEST_CHECK(HeapDestroy(privateHeap));
|
|
|
|
SetLastError(0);
|
|
TEST_CHECK(!HeapDestroy(processHeap));
|
|
TEST_CHECK_EQ(ERROR_INVALID_HANDLE, GetLastError());
|
|
}
|
|
|
|
static void test_large_alloc() {
|
|
HANDLE heap = HeapCreate(0, 0, 0);
|
|
TEST_CHECK(heap != NULL);
|
|
|
|
// Test allocating a large block
|
|
void *largeBlock = HeapAlloc(heap, 0, LARGE_BLOCK_SIZE);
|
|
*(uint32_t *)largeBlock = 0x12345678;
|
|
TEST_CHECK(largeBlock != NULL);
|
|
SIZE_T blockSize = HeapSize(heap, 0, largeBlock);
|
|
TEST_CHECK(blockSize >= LARGE_BLOCK_SIZE);
|
|
|
|
// Test reallocating a large block to a smaller size
|
|
void *smallBlock = HeapReAlloc(heap, 0, largeBlock, SMALL_BLOCK_SIZE);
|
|
TEST_CHECK(smallBlock != NULL);
|
|
TEST_CHECK(*(uint32_t *)smallBlock == 0x12345678);
|
|
blockSize = HeapSize(heap, 0, smallBlock);
|
|
TEST_CHECK(blockSize >= SMALL_BLOCK_SIZE);
|
|
|
|
// Test reallocating a small block to a larger size
|
|
largeBlock = HeapReAlloc(heap, 0, smallBlock, LARGE_BLOCK_SIZE);
|
|
TEST_CHECK(largeBlock != NULL);
|
|
TEST_CHECK(*(uint32_t *)largeBlock == 0x12345678);
|
|
TEST_CHECK(HeapFree(heap, 0, largeBlock));
|
|
|
|
TEST_CHECK(HeapDestroy(heap));
|
|
}
|
|
|
|
static void test_heap_expansion() {
|
|
HANDLE heap = HeapCreate(0, 0, 0);
|
|
TEST_CHECK(heap != NULL);
|
|
|
|
// Test allocating a total of 768 MiB
|
|
const SIZE_T TOTAL_SIZE = 768ULL * 1024ULL * 1024ULL;
|
|
for (int i = 0; i < (int)(TOTAL_SIZE / SMALL_BLOCK_SIZE); i++) {
|
|
void *block = HeapAlloc(heap, 0, SMALL_BLOCK_SIZE);
|
|
TEST_CHECK(block != NULL);
|
|
}
|
|
|
|
TEST_CHECK(HeapDestroy(heap));
|
|
}
|
|
|
|
int main(void) {
|
|
test_basics();
|
|
test_large_alloc();
|
|
test_heap_expansion();
|
|
return EXIT_SUCCESS;
|
|
}
|