A test application for the boot loader heap allocator.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3642 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <boot/platform.h>
|
||||||
|
#include <boot/heap.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void *heap_malloc(size_t size);
|
||||||
|
extern "C" void heap_free(void *buffer);
|
||||||
|
extern void dump_chunks(void);
|
||||||
|
extern int32 heap_available(void);
|
||||||
|
|
||||||
|
|
||||||
|
const int32 kHeapSize = 32 * 1024;
|
||||||
|
|
||||||
|
int32 gVerbosity = 1;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
platform_release_heap(void *base)
|
||||||
|
{
|
||||||
|
free(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
platform_init_heap(struct stage2_args *args, void **_base, void **_top)
|
||||||
|
{
|
||||||
|
void *base = malloc(kHeapSize);
|
||||||
|
if (base == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
*_base = base;
|
||||||
|
*_top = (void *)((uint8 *)base + kHeapSize);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
panic(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_allocated_chunk(int32 index, void *buffer)
|
||||||
|
{
|
||||||
|
if (buffer == NULL || gVerbosity < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t *size = (size_t *)((uint8 *)buffer - sizeof(uint32));
|
||||||
|
printf("\t%ld. allocation at %p, chunk at %p, size = %ld\n", index, buffer, size, *size);
|
||||||
|
|
||||||
|
if (gVerbosity > 3)
|
||||||
|
dump_chunks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
test_malloc(size_t bytes)
|
||||||
|
{
|
||||||
|
return heap_malloc(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_free(void *buffer)
|
||||||
|
{
|
||||||
|
if (gVerbosity > 4) {
|
||||||
|
printf("\tfreeing buffer at %p\n", buffer);
|
||||||
|
dump_allocated_chunk(-1, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_free(buffer);
|
||||||
|
|
||||||
|
if (gVerbosity > 4) {
|
||||||
|
puts("\t- after:");
|
||||||
|
dump_chunks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
random_allocations(void *array[], size_t maxSize)
|
||||||
|
{
|
||||||
|
printf("* random allocations (up to %ld bytes)\n", maxSize);
|
||||||
|
|
||||||
|
size_t total = 0;
|
||||||
|
int32 count = 0;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < 100; i++) {
|
||||||
|
size_t size = size_t(rand() * 1. * maxSize / RAND_MAX);
|
||||||
|
array[i] = test_malloc(size);
|
||||||
|
if (array[i] == NULL) {
|
||||||
|
if ((size > heap_available() || size == 0) && gVerbosity < 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printf( "%ld. allocating %ld bytes failed (%ld bytes total allocated, "
|
||||||
|
"%ld free (%ld))\n",
|
||||||
|
i, size, total, heap_available(), kHeapSize - total);
|
||||||
|
} else {
|
||||||
|
dump_allocated_chunk(i, array[i]);
|
||||||
|
|
||||||
|
total += size;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\t%ld bytes allocated\n", total);
|
||||||
|
if (gVerbosity > 3)
|
||||||
|
dump_chunks();
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc > 1)
|
||||||
|
gVerbosity = atoi(argv[1]);
|
||||||
|
|
||||||
|
stage2_args args;
|
||||||
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
|
if (heap_init(&args) < B_OK) {
|
||||||
|
fprintf(stderr, "Could not initialize heap.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("heap size == %ld\n", kHeapSize);
|
||||||
|
if (gVerbosity > 2)
|
||||||
|
dump_chunks();
|
||||||
|
|
||||||
|
puts("* simple allocation of 100 * 128 bytes");
|
||||||
|
void *array[100];
|
||||||
|
for (int32 i = 0; i < 100; i++) {
|
||||||
|
array[i] = test_malloc(128);
|
||||||
|
dump_allocated_chunk(i, array[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gVerbosity > 2)
|
||||||
|
dump_chunks();
|
||||||
|
|
||||||
|
puts("* testing different deleting order");
|
||||||
|
if (gVerbosity > 2)
|
||||||
|
puts("- free 30 from the end (descending):");
|
||||||
|
|
||||||
|
for (int32 i = 100; i-- > 70; ) {
|
||||||
|
test_free(array[i]);
|
||||||
|
array[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gVerbosity > 2) {
|
||||||
|
dump_chunks();
|
||||||
|
puts("- free 40 from the middle (ascending):");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 i = 30; i < 70; i++) {
|
||||||
|
test_free(array[i]);
|
||||||
|
array[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gVerbosity > 2) {
|
||||||
|
dump_chunks();
|
||||||
|
puts("- free 30 from the start (ascending):");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 i = 0; i < 30; i++) {
|
||||||
|
test_free(array[i]);
|
||||||
|
array[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gVerbosity > 2)
|
||||||
|
dump_chunks();
|
||||||
|
|
||||||
|
puts("* allocate until it fails");
|
||||||
|
int32 i = 0;
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
array[i] = test_malloc(kHeapSize / 64);
|
||||||
|
if (array[i] == NULL) {
|
||||||
|
printf("\tallocation %ld failed - could allocate %ld bytes (64th should fail).\n", i + 1, (kHeapSize / 64) * (i + 1));
|
||||||
|
|
||||||
|
if (gVerbosity > 2)
|
||||||
|
dump_chunks();
|
||||||
|
|
||||||
|
while (i-- > 0) {
|
||||||
|
test_free(array[i]);
|
||||||
|
array[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
dump_allocated_chunk(i, array[i]);
|
||||||
|
}
|
||||||
|
if (i == 100)
|
||||||
|
fprintf(stderr, "could allocate more memory than in heap\n");
|
||||||
|
|
||||||
|
random_allocations(array, 768);
|
||||||
|
|
||||||
|
puts("* free memory again");
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
test_free(array[i]);
|
||||||
|
array[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t amount = 32; amount < 1024; amount *= 2) {
|
||||||
|
int32 count = random_allocations(array, amount);
|
||||||
|
|
||||||
|
puts("* random freeing");
|
||||||
|
while (count) {
|
||||||
|
i = int32(rand() * 100. / RAND_MAX);
|
||||||
|
if (array[i] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
test_free(array[i]);
|
||||||
|
array[i] = NULL;
|
||||||
|
count--;
|
||||||
|
|
||||||
|
if (gVerbosity > 2) {
|
||||||
|
puts("- freed one");
|
||||||
|
dump_chunks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_release();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user