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
};
|