Files
hawk/t/t-009.c

207 lines
4.6 KiB
C
Raw Permalink Normal View History

2025-06-14 23:16:45 +09:00
#include <hawk-xma.h>
#include <hawk-std.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "tap.h"
2025-07-14 22:55:48 +09:00
#define NUM_ITERATIONS 20000
#define MAX_ALLOC_ACTIVE 1000
2025-06-14 23:16:45 +09:00
#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;
2025-06-14 23:27:55 +09:00
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);
}
2025-07-14 22:55:48 +09:00
static size_t random_size(hawk_oow_t max_alloc_size)
2025-06-14 23:16:45 +09:00
{
2025-07-14 22:55:48 +09:00
return MIN_ALLOC_SIZE + rand() % (max_alloc_size - MIN_ALLOC_SIZE + 1);
2025-06-14 23:16:45 +09:00
}
2025-07-14 22:55:48 +09:00
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[])
2025-06-14 23:16:45 +09:00
{
int test_bad = 0;
hawk_mmgr_t xma_mmgr;
2025-07-14 22:55:48 +09:00
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;
2025-06-14 23:16:45 +09:00
2025-07-14 22:55:48 +09:00
Allocation* allocations; /* pool of active allocations */
2025-06-14 23:16:45 +09:00
size_t num_active = 0;
2025-07-15 23:48:07 +09:00
size_t i;
2025-06-14 23:16:45 +09:00
clock_t start_time, end_time;
double malloc_time = 0.0, free_time = 0.0;
2025-07-14 22:55:48 +09:00
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;
}
2025-06-14 23:27:55 +09:00
no_plan();
2025-07-14 22:55:48 +09:00
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);
/* ------------------------------- */
2025-06-14 23:27:55 +09:00
srand((unsigned int)time(NULL));
2025-06-14 23:16:45 +09:00
start_time = clock();
2025-07-15 23:48:07 +09:00
for (i = 0; i < num_iterations; ++i)
2025-06-14 23:16:45 +09:00
{
2025-07-14 22:55:48 +09:00
int do_alloc = (num_active == 0) || (rand() % 2 == 0 && num_active < max_alloc_active);
2025-06-14 23:16:45 +09:00
if (do_alloc) {
2025-07-14 22:55:48 +09:00
size_t size = random_size(max_alloc_size);
2025-06-14 23:27:55 +09:00
/*void *ptr = malloc(size);*/
2025-06-14 23:16:45 +09:00
void *ptr = HAWK_MMGR_ALLOC(&xma_mmgr, size);
if (!ptr) {
fprintf(stderr, "malloc failed at operation %zu\n", i);
2025-06-14 23:27:55 +09:00
test_bad = 1;
2025-06-14 23:16:45 +09:00
break;
}
allocations[num_active].ptr = ptr;
allocations[num_active].size = size;
++num_active;
} else {
2025-07-14 22:55:48 +09:00
/* free a random active allocation */
2025-07-15 23:48:07 +09:00
clock_t t1, t2;
2025-06-14 23:16:45 +09:00
size_t index = rand() % num_active;
void *ptr_to_free = allocations[index].ptr;
2025-07-15 23:48:07 +09:00
t1 = clock();
2025-06-14 23:27:55 +09:00
/*free(ptr_to_free); */
2025-06-14 23:16:45 +09:00
HAWK_MMGR_FREE(&xma_mmgr, ptr_to_free);
2025-07-15 23:48:07 +09:00
t2 = clock();
2025-06-14 23:16:45 +09:00
free_time += (double)(t2 - t1) / CLOCKS_PER_SEC;
2025-07-14 22:55:48 +09:00
/* replace with last active allocation */
2025-06-14 23:16:45 +09:00
allocations[index] = allocations[num_active - 1];
--num_active;
}
}
2025-06-14 23:27:55 +09:00
OK_X(test_bad == 0);
/* hawk_xma_dump(xma_mmgr.ctx, print_xma, HAWK_NULL); */
2025-06-14 23:16:45 +09:00
2025-06-14 23:27:55 +09:00
/* Free remaining allocations */
2025-07-15 23:48:07 +09:00
for (i = 0; i < num_active; ++i) {
2025-06-14 23:27:55 +09:00
/* free(allocations[i].ptr); */
2025-06-14 23:16:45 +09:00
HAWK_MMGR_FREE(&xma_mmgr, allocations[i].ptr);
}
end_time = clock();
2025-06-14 23:27:55 +09:00
hawk_xma_dump(xma_mmgr.ctx, print_xma, HAWK_NULL);
2025-06-14 23:16:45 +09:00
malloc_time = (double)(end_time - start_time) / CLOCKS_PER_SEC - free_time;
2025-07-14 22:55:48 +09:00
printf("Performed %d interleaved malloc/free operations\n", num_iterations);
2025-06-14 23:16:45 +09:00
printf("Total malloc time (estimated): %.6f seconds\n", malloc_time);
printf("Total free time : %.6f seconds\n", free_time);
2025-07-14 22:55:48 +09:00
printf("Average time per operation : %.9f seconds\n", (malloc_time + free_time) / num_iterations);
2025-06-14 23:16:45 +09:00
2025-07-14 22:55:48 +09:00
HAWK_MMGR_FREE(&xma_mmgr, allocations);
hawk_fini_xma_mmgr(&xma_mmgr);
2025-06-14 23:27:55 +09:00
return exit_status();
2025-06-14 23:16:45 +09:00
}