summaryrefslogtreecommitdiff
path: root/test/test_cxalloc.c
blob: 267f314832827f68f5c7125dfcdbfbce6b5e721a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "test_common.h"

#include <stdarg.h>
#include <usual/string.h>
#include <usual/cxextra.h>

static int delta = 0;

static char logbuf[1024];

static void reset(void)
{
	logbuf[0] = 0;
}

_PRINTF(1,2)
static void m_log(const char *fmt, ...)
{
	size_t len = strlen(logbuf);
	va_list ap;

	if (len && len < sizeof(logbuf) - 1)
		logbuf[len++] = ' ';

	va_start(ap, fmt);
	vsnprintf(logbuf + len, sizeof(logbuf) - len, fmt, ap);
	va_end(ap);
}

static void *log_alloc(void *ctx, size_t len)
{
	void *p;
	m_log("A(%d)", (int)len);
	delta += len;
	p = cx_alloc(ctx, len + 8);
	*(int*)p = len;
	return (char *)p + 8;
}

static void *log_realloc(void *ctx, void *ptr, size_t len)
{
	char *p = (char *)ptr - 8;
	int olen = *(int*)p;
	m_log("R(%d)", (int)len);
	p = cx_realloc(ctx, p, len + 8);
	*(int*)p = len;
	delta += len - olen;
	return p + 8;
}

static void log_free(void *ctx, const void *ptr)
{
	char *p = (char *)ptr - 8;
	int len = *(int*)p;
	delta -= len;
	m_log("F(%d)", len);
	cx_free(ctx, p);
}

static const struct CxOps log_ops = {
	log_alloc,
	log_realloc,
	log_free,
};

static const struct CxMem log_libc = {
	&log_ops,
	(void*)&cx_libc_allocator,
};

#define log_check(x) str_check(logbuf, x); reset();

static void test_cxalloc_basic(void *zzz)
{
	CxMem *cx = &log_libc;
	void *p;
	delta = 0;
	p = cx_alloc(cx, 16);
	log_check("A(16)")
	p = cx_realloc(cx, p, 500);
	log_check("R(500)")
	cx_free(cx, p);
	log_check("F(500)");
	int_check(delta, 0);
end:
	reset();
}

static void test_cxalloc_tree(void *zzz)
{
	CxMem *cx1, *cx2;
	void *p;
	delta = 0;
	cx1 = cx_new_tree(&log_libc);
	p = cx_alloc(cx1, 16);
	p = cx_realloc(cx1, p, 500);
	p = cx_realloc(cx1, p, 1500);
	p = cx_alloc(cx1, 55);
	cx_free(cx1, p);

	cx2 = cx_new_tree(cx1);
	p = cx_realloc(cx2, NULL, 2500);
	cx2 = cx_new_tree(cx2);
	p = cx_realloc(cx2, NULL, 3500);

	cx_destroy(cx1);

	/* str_check(logbuf, "A(16)R(500)F()"); */
	int_check(delta, 0);
end:
	reset();
}

struct testcase_t cxalloc_tests[] = {
	{ "basic", test_cxalloc_basic },
	{ "tree", test_cxalloc_tree },
	END_OF_TESTCASES
};