207 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <hawk.h>
 | 
						|
#include <hawk-xma.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <time.h>
 | 
						|
#include "tap.h"
 | 
						|
 | 
						|
#define NUM_ITERATIONS 20000
 | 
						|
#define MAX_ALLOC_ACTIVE 1000
 | 
						|
#define MIN_ALLOC_SIZE 16
 | 
						|
#define MAX_ALLOC_SIZE 1024
 | 
						|
 | 
						|
#define OK_X(test) OK(test, #test)
 | 
						|
 | 
						|
 | 
						|
typedef struct {
 | 
						|
	void *ptr;
 | 
						|
	size_t size;
 | 
						|
} Allocation;
 | 
						|
 | 
						|
 | 
						|
static void print_xma (void* ctx, const hawk_bch_t* fmt, ...)
 | 
						|
{
 | 
						|
     va_list ap;
 | 
						|
     va_start (ap, fmt);
 | 
						|
     vfprintf (stderr, fmt, ap);
 | 
						|
     va_end (ap);
 | 
						|
}
 | 
						|
 | 
						|
static size_t random_size(hawk_oow_t max_alloc_size)
 | 
						|
{
 | 
						|
	return MIN_ALLOC_SIZE + rand() % (max_alloc_size - MIN_ALLOC_SIZE + 1);
 | 
						|
}
 | 
						|
 | 
						|
static void test1(hawk_mmgr_t* mmgr)
 | 
						|
{
 | 
						|
	void* x1, * x2, * x3;
 | 
						|
 | 
						|
	x1 = HAWK_MMGR_ALLOC(mmgr, 416);
 | 
						|
	OK_X (x1 != HAWK_NULL);
 | 
						|
	x2 = HAWK_MMGR_ALLOC(mmgr, 688);
 | 
						|
	OK_X (x2 != HAWK_NULL);
 | 
						|
 | 
						|
	HAWK_MMGR_FREE(mmgr, x1);
 | 
						|
	HAWK_MMGR_FREE(mmgr, x2);
 | 
						|
	x3 = HAWK_MMGR_ALLOC(mmgr, 144);
 | 
						|
	OK_X (x2 != HAWK_NULL);
 | 
						|
 | 
						|
	HAWK_MMGR_FREE(mmgr, x3);
 | 
						|
	/*hawk_xma_dump(mmgr.ctx, print_xma, HAWK_NULL);*/
 | 
						|
}
 | 
						|
 | 
						|
static void test2(hawk_mmgr_t* mmgr)
 | 
						|
{
 | 
						|
	int x[] =
 | 
						|
	{
 | 
						|
		960, 688, -688, -960, 560, 32, -560, -32, 336, 624, -624, -336, 672, -672, 304, -304, 992, -992, 608, -608,
 | 
						|
		576, 304, 256,  -304, -256, 416,
 | 
						|
	};
 | 
						|
	int i, j;
 | 
						|
	int count;
 | 
						|
	void *p[100];
 | 
						|
	int sz[100];
 | 
						|
	int test2_bad = 0;
 | 
						|
	
 | 
						|
	count = 0;
 | 
						|
	for (i = 0; i < HAWK_COUNTOF(x); i++)
 | 
						|
	{
 | 
						|
		if (x[i] > 0)
 | 
						|
		{
 | 
						|
			p[count] = HAWK_MMGR_ALLOC(mmgr, x[i]);
 | 
						|
			if (!p[count])
 | 
						|
			{
 | 
						|
				test2_bad = 1;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			sz[count] = x[i];
 | 
						|
			count++;
 | 
						|
		}
 | 
						|
		else if (x[i] < 0)
 | 
						|
		{
 | 
						|
			for (j = 0; j < count; j++)
 | 
						|
			{
 | 
						|
				if (sz[j] == -x[i])
 | 
						|
				{
 | 
						|
					HAWK_MMGR_FREE(mmgr, p[j]);
 | 
						|
					count--;
 | 
						|
					p[j] = p[count];
 | 
						|
					sz[j] = sz[count];	
 | 
						|
				}
 | 
						|
			}	
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*hawk_xma_dump(mmgr->ctx, print_xma, HAWK_NULL);*/
 | 
						|
 | 
						|
	OK_X(test2_bad == 0);
 | 
						|
	for (j = 0; j < count; j++) HAWK_MMGR_FREE(mmgr, p[j]);
 | 
						|
}
 | 
						|
 | 
						|
int main(int argc, char* argv[])
 | 
						|
{
 | 
						|
	int test_bad = 0;
 | 
						|
	hawk_mmgr_t xma_mmgr;
 | 
						|
	hawk_oow_t max_alloc_size = MAX_ALLOC_SIZE;
 | 
						|
	hawk_oow_t num_iterations = NUM_ITERATIONS;
 | 
						|
	hawk_oow_t max_alloc_active = MAX_ALLOC_ACTIVE;
 | 
						|
	hawk_oow_t pool_size = 1000000;
 | 
						|
 | 
						|
	Allocation* allocations; /* pool of active allocations */
 | 
						|
	size_t num_active = 0;
 | 
						|
	size_t i;
 | 
						|
 | 
						|
	clock_t start_time, end_time;
 | 
						|
	double malloc_time = 0.0, free_time = 0.0;
 | 
						|
 | 
						|
	if (argc >= 5)
 | 
						|
	{
 | 
						|
		num_iterations = strtoul(argv[1], NULL, 10);
 | 
						|
		max_alloc_size = strtoul(argv[2], NULL, 10);
 | 
						|
		max_alloc_active = strtoul(argv[3], NULL, 10);
 | 
						|
		pool_size = strtoul(argv[4], NULL, 10);
 | 
						|
	}
 | 
						|
	else if (argc != 1)
 | 
						|
	{
 | 
						|
		fprintf (stderr, "Usage: %s num_iterations max_alloc_size max_alloc_active pool_size\n", argv[0]);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	no_plan();
 | 
						|
	hawk_init_xma_mmgr(&xma_mmgr, pool_size);
 | 
						|
 | 
						|
	allocations = HAWK_MMGR_ALLOC(&xma_mmgr, max_alloc_active * sizeof(*allocations));
 | 
						|
	if (!allocations)
 | 
						|
	{
 | 
						|
		bail_out("base allocation failed");
 | 
						|
		return -1;	
 | 
						|
	}
 | 
						|
	
 | 
						|
	/* ------------------------------- */
 | 
						|
	test1(&xma_mmgr);
 | 
						|
	test2(&xma_mmgr);
 | 
						|
 | 
						|
	/* ------------------------------- */
 | 
						|
 | 
						|
	srand((unsigned int)time(NULL));
 | 
						|
	start_time = clock();
 | 
						|
 | 
						|
	for (i = 0; i < num_iterations; ++i)
 | 
						|
	{
 | 
						|
		int do_alloc = (num_active == 0) || (rand() % 2 == 0 && num_active < max_alloc_active);
 | 
						|
 | 
						|
		if (do_alloc) {
 | 
						|
			size_t size = random_size(max_alloc_size);
 | 
						|
			/*void *ptr = malloc(size);*/
 | 
						|
			void *ptr = HAWK_MMGR_ALLOC(&xma_mmgr, size);
 | 
						|
			if (!ptr) {
 | 
						|
				fprintf(stderr, "malloc failed at operation %zu\n", i);
 | 
						|
				test_bad = 1;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
 | 
						|
			allocations[num_active].ptr = ptr;
 | 
						|
			allocations[num_active].size = size;
 | 
						|
			++num_active;
 | 
						|
		} else {
 | 
						|
			/* free a random active allocation */
 | 
						|
			clock_t t1, t2;
 | 
						|
			size_t index = rand() % num_active;
 | 
						|
			void *ptr_to_free = allocations[index].ptr;
 | 
						|
 | 
						|
			t1 = clock();
 | 
						|
			/*free(ptr_to_free); */
 | 
						|
			HAWK_MMGR_FREE(&xma_mmgr, ptr_to_free);
 | 
						|
			t2 = clock();
 | 
						|
			free_time += (double)(t2 - t1) / CLOCKS_PER_SEC;
 | 
						|
 | 
						|
			/* replace with last active allocation */
 | 
						|
			allocations[index] = allocations[num_active - 1];
 | 
						|
			--num_active;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	OK_X(test_bad == 0);
 | 
						|
 | 
						|
	/* hawk_xma_dump(xma_mmgr.ctx, print_xma, HAWK_NULL); */
 | 
						|
 | 
						|
	/* Free remaining allocations */
 | 
						|
	for (i = 0; i < num_active; ++i) {
 | 
						|
		/* free(allocations[i].ptr); */
 | 
						|
		HAWK_MMGR_FREE(&xma_mmgr, allocations[i].ptr);
 | 
						|
	}
 | 
						|
 | 
						|
	end_time = clock();
 | 
						|
	hawk_xma_dump(xma_mmgr.ctx, print_xma, HAWK_NULL);
 | 
						|
 | 
						|
	malloc_time = (double)(end_time - start_time) / CLOCKS_PER_SEC - free_time;
 | 
						|
 | 
						|
	printf("Performed %lu interleaved malloc/free operations\n", (unsigned long)num_iterations);
 | 
						|
	printf("Total malloc time (estimated): %.6f seconds\n", malloc_time);
 | 
						|
	printf("Total free time              : %.6f seconds\n", free_time);
 | 
						|
	printf("Average time per operation   : %.9f seconds\n", (malloc_time + free_time) / num_iterations);
 | 
						|
 | 
						|
	HAWK_MMGR_FREE(&xma_mmgr, allocations);
 | 
						|
	hawk_fini_xma_mmgr(&xma_mmgr);
 | 
						|
	return exit_status();
 | 
						|
}
 | 
						|
 |