-
Notifications
You must be signed in to change notification settings - Fork 0
/
alloc.c
124 lines (102 loc) · 2.08 KB
/
alloc.c
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
120
121
122
/**
* Author: Humberto Naves ([email protected])
*/
#include <stdlib.h>
#include <string.h>
#include "alloc.h"
#include "utils.h"
struct _link {
struct _link *next;
size_t size;
};
struct _fixedpool {
struct _link *allocated;
struct _link *nextfree;
size_t size;
size_t grownum;
size_t bytes;
int setzero;
};
fixedpool fixedpool_create (size_t size, size_t grownum, int setzero)
{
fixedpool p = (fixedpool) xmalloc (sizeof (struct _fixedpool));
if (size < sizeof (struct _link)) size = sizeof (struct _link);
if (grownum < 2) grownum = 2;
p->size = size;
p->grownum = grownum;
p->allocated = NULL;
p->nextfree = NULL;
p->bytes = 0;
p->setzero = setzero;
return p;
}
void fixedpool_destroy (fixedpool p, pooltraversefn destroyfn, void *arg)
{
struct _link *ptr, *nptr;
char *c;
size_t count;
for (ptr = p->allocated; ptr; ptr = nptr) {
if (destroyfn) {
c = (char *) ptr;
c += p->size;
count = 2 * p->size;
while (count <= ptr->size) {
destroyfn (c, arg);
c += p->size;
count += p->size;
}
}
nptr = ptr->next;
free (ptr);
}
p->allocated = NULL;
p->nextfree = NULL;
free (p);
}
void fixedpool_grow (fixedpool p, void *ptr, size_t ptrsize)
{
char *c;
struct _link *l;
size_t count;
if (ptrsize < 2 * p->size) {
free (ptr);
return;
}
l = ptr;
l->next = p->allocated;
l->size = ptrsize;
p->bytes += ptrsize;
p->allocated = l;
c = ptr;
c += p->size;
count = 2 * p->size;
while (count <= ptrsize) {
l = (struct _link *) c;
l->next = p->nextfree;
p->nextfree = l;
c += p->size;
count += p->size;
}
}
void *fixedpool_alloc (fixedpool p)
{
struct _link *l;
if (!p->nextfree) {
size_t size;
void *ptr;
size = p->grownum * p->size;
ptr = xmalloc (size);
fixedpool_grow (p, ptr, size);
}
l = p->nextfree;
p->nextfree = l->next;
if (p->setzero)
memset (l, 0, p->size);
return (void *) l;
}
void fixedpool_free (fixedpool p, void *ptr)
{
struct _link *l = ptr;
l->next = p->nextfree;
p->nextfree = l;
}