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
|
#include <stdlib.h>
#include <string.h>
#include "stalloc.h"
struct st_alloc_t {
int nb_pools;
char ** mem_pools;
size_t * pools_size;
};
struct st_alloc_t * st_init() {
struct st_alloc_t * r = (struct st_alloc_t *) malloc(sizeof(struct st_alloc_t));
if (r) {
r->nb_pools = 0;
r->mem_pools = 0;
r->pools_size = 0;
}
return r;
}
#define POOL_SIZE 16384
static int create_pool(struct st_alloc_t * s) {
s->nb_pools++;
// No error checking, because it'd be a pain to handle.
s->mem_pools = (char **) realloc(s->mem_pools, sizeof(char *) * s->nb_pools);
s->pools_size = (size_t *) realloc(s->pools_size, sizeof(size_t) * s->nb_pools);
s->mem_pools[s->nb_pools - 1] = malloc(POOL_SIZE);
s->pools_size[s->nb_pools - 1] = 0;
return s->nb_pools - 1;
}
static int search_pool(struct st_alloc_t * s, size_t siz) {
int i;
// This algorithm could use a little bit more of cleverness, but... *shrug*
// the whole purpose is to be used for small static strings, so...
for (i = 0; i < s->nb_pools; i++) {
if (siz <= (POOL_SIZE - s->pools_size[i]))
return i;
}
return -1;
}
void * st_alloc(struct st_alloc_t * s, size_t siz) {
int pool;
if (siz > POOL_SIZE) {
pool = create_pool(s);
s->mem_pools[pool] = realloc(s->mem_pools[pool], siz);
s->pools_size[pool] = siz;
return s->mem_pools[pool];
}
pool = search_pool(s, siz);
if (pool < 0)
pool = create_pool(s);
s->pools_size[pool] += siz;
return s->mem_pools[pool] + s->pools_size[pool] - siz;
}
char * st_strdup(struct st_alloc_t * s, const char * src) {
int siz = strlen(src) + 1;
char * r = (char *) st_alloc(s, siz);
memcpy(r, src, siz);
return r;
}
void st_destroy(struct st_alloc_t * s) {
int i;
for (i = 0; i < s->nb_pools; i++) {
free(s->mem_pools[i]);
}
free(s->mem_pools);
free(s->pools_size);
free(s);
}
|