Groonga 3.0.9 Source Code Document
Main Page
Related Pages
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Pages
groonga
vendor
mruby-eeac4be
src
pool.c
Go to the documentation of this file.
1
/*
2
** pool.c - memory pool
3
**
4
** See Copyright Notice in mruby.h
5
*/
6
7
#include <stddef.h>
8
#include <
string.h
>
9
#include "
mruby.h
"
10
11
/* configuration section */
12
/* allocated memory address should be multiple of POOL_ALIGNMENT */
13
/* or undef it if alignment does not matter */
14
#ifndef POOL_ALIGNMENT
15
#define POOL_ALIGNMENT 4
16
#endif
17
/* page size of memory pool */
18
#ifndef POOL_PAGE_SIZE
19
#define POOL_PAGE_SIZE 16000
20
#endif
21
/* end of configuration section */
22
23
struct
mrb_pool_page
{
24
struct
mrb_pool_page
*
next
;
25
size_t
offset
;
26
size_t
len
;
27
void
*
last
;
28
char
page
[];
29
};
30
31
struct
mrb_pool
{
32
mrb_state
*
mrb
;
33
struct
mrb_pool_page
*
pages
;
34
};
35
36
#undef TEST_POOL
37
#ifdef TEST_POOL
38
39
#define mrb_malloc(m,s) malloc(s)
40
#define mrb_free(m,p) free(p)
41
#endif
42
43
#ifdef POOL_ALIGNMENT
44
# define ALIGN_PADDING(x) ((-x) & (POOL_ALIGNMENT - 1))
45
#else
46
# define ALIGN_PADDING(x) (0)
47
#endif
48
49
mrb_pool
*
50
mrb_pool_open
(
mrb_state
*mrb)
51
{
52
mrb_pool
*pool = (
mrb_pool
*)
mrb_malloc
(mrb,
sizeof
(
mrb_pool
));
53
54
if
(pool) {
55
pool->
mrb
= mrb;
56
pool->
pages
= NULL;
57
}
58
59
return
pool;
60
}
61
62
void
63
mrb_pool_close
(
mrb_pool
*pool)
64
{
65
struct
mrb_pool_page
*
page
, *tmp;
66
67
if
(!pool)
return
;
68
page = pool->
pages
;
69
while
(page) {
70
tmp =
page
;
71
page = page->
next
;
72
mrb_free
(pool->
mrb
, tmp);
73
}
74
mrb_free
(pool->
mrb
, pool);
75
}
76
77
static
struct
mrb_pool_page
*
78
page_alloc(
mrb_pool
*pool,
size_t
len
)
79
{
80
struct
mrb_pool_page
*
page
;
81
82
if
(len <
POOL_PAGE_SIZE
)
83
len =
POOL_PAGE_SIZE
;
84
page = (
struct
mrb_pool_page
*)
mrb_malloc
(pool->
mrb
,
sizeof
(
struct
mrb_pool_page
)+
len
);
85
if
(page) {
86
page->
offset
= 0;
87
page->
len
=
len
;
88
}
89
90
return
page
;
91
}
92
93
void
*
94
mrb_pool_alloc
(
mrb_pool
*pool,
size_t
len)
95
{
96
struct
mrb_pool_page
*
page
;
97
size_t
n;
98
99
if
(!pool)
return
NULL;
100
len +=
ALIGN_PADDING
(len);
101
page = pool->
pages
;
102
while
(page) {
103
if
(page->
offset
+ len <= page->len) {
104
n = page->
offset
;
105
page->
offset
+=
len
;
106
page->
last
= (
char
*)page->
page
+n;
107
return
page->
last
;
108
}
109
page = page->
next
;
110
}
111
page = page_alloc(pool, len);
112
if
(!page)
return
NULL;
113
page->
offset
=
len
;
114
page->
next
= pool->
pages
;
115
pool->
pages
=
page
;
116
117
page->
last
= (
void
*)page->
page
;
118
return
page->
last
;
119
}
120
121
mrb_bool
122
mrb_pool_can_realloc
(
mrb_pool
*pool,
void
*p,
size_t
len)
123
{
124
struct
mrb_pool_page
*
page
;
125
126
if
(!pool)
return
FALSE
;
127
len +=
ALIGN_PADDING
(len);
128
page = pool->
pages
;
129
while
(page) {
130
if
(page->
last
== p) {
131
size_t
beg;
132
133
beg = (
char
*)p - page->
page
;
134
if (beg + len > page->
len
)
return
FALSE
;
135
return
TRUE
;
136
}
137
page = page->
next
;
138
}
139
return
FALSE
;
140
}
141
142
void
*
143
mrb_pool_realloc
(
mrb_pool
*pool,
void
*p,
size_t
oldlen,
size_t
newlen)
144
{
145
struct
mrb_pool_page
*
page
;
146
void
*np;
147
148
if
(!pool)
return
NULL;
149
oldlen +=
ALIGN_PADDING
(oldlen);
150
newlen +=
ALIGN_PADDING
(newlen);
151
page = pool->
pages
;
152
while
(page) {
153
if
(page->
last
== p) {
154
size_t
beg;
155
156
beg = (
char
*)p - page->
page
;
157
if (beg + oldlen != page->
offset
)
break
;
158
if
(beg + newlen > page->
len
) {
159
page->
offset
= beg;
160
break
;
161
}
162
page->
offset
= beg + newlen;
163
return
p;
164
}
165
page = page->
next
;
166
}
167
np =
mrb_pool_alloc
(pool, newlen);
168
memcpy(np, p, oldlen);
169
return
np;
170
}
171
172
#ifdef TEST_POOL
173
int
174
main
(
void
)
175
{
176
int
i
, len = 250;
177
mrb_pool
*pool;
178
void
*p;
179
180
pool =
mrb_pool_open
(NULL);
181
p =
mrb_pool_alloc
(pool, len);
182
for
(i=1; i<20; i++) {
183
printf(
"%p (len=%d) %ud\n"
, p, len,
mrb_pool_can_realloc
(pool, p, len*2));
184
p =
mrb_pool_realloc
(pool, p, len, len*2);
185
len *= 2;
186
}
187
mrb_pool_close
(pool);
188
return
0;
189
}
190
#endif
Generated on Sun Nov 10 2013 09:49:06 for Groonga 3.0.9 Source Code Document by
1.8.1.2