-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchunk-alloc.h
211 lines (174 loc) · 6.18 KB
/
chunk-alloc.h
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/* PET
* Platform for Experimentation with efficient HPSG processing Techniques
* (C) 1999 - 2002 Ulrich Callmeier [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \file chunk-alloc.h
* Manage chunks of memory for efficient allocation of objects.
*/
#ifndef _CHUNK_ALLOC_H_
#define _CHUNK_ALLOC_H_
#include <sys/types.h>
#include <cstdio>
/** The maximum number of chunks to allocate */
#define MAX_CHUNKS 16000
/** The desired chunk size */
#define CHUNK_SIZE (1024 * 1024)
/** Define a type for (nasty) pointer to int conversions */
#if SIZEOF_INT_P == 4
typedef int32_t ptr2int_t;
typedef u_int32_t ptr2uint_t;
#else
#if SIZEOF_INT_P == 8
typedef int64_t ptr2int_t;
typedef u_int64_t ptr2uint_t;
#endif
#endif
/** Class to support stack-like allocation/deallocation by keeping a pointer
* into a growing allocated heap of memory.
*/
typedef struct chunk_alloc_state
{
int c;
int p;
} chunk_alloc_state;
/** Class to manage chunks of memory for efficient allocation of objects
This class has several implementations of its low-level memory allocation,
one that is unix dependend, supporting two heaps with disjunct and
easy to distinguish address rooms to allow zero-overhead seperation
of permanent and non-permant dags (colored pointers); another windows-
specific implementation that uses VirtualAlloc; and a third one that
relies on standard C++ memory management only
(somewhat like obstacks in gcc) */
class chunk_allocator
{
public:
/** Create a chunk allocator with (approximate) chunk size \a chunk_size.
* \param chunk_size The (approximate) size of one allocated chunk.
* \param down (only useful if mmap is used, i.e., on *nix platforms:
* if \c true, allocate chunks down from the upper end of the address
* space, otherwise, start at the lower end and grow upwards.
*/
chunk_allocator(int chunk_size, bool down = false);
~chunk_allocator();
/** Get another \a n bytes from the chunk allocator */
inline void* allocate(int n)
{
if((_chunk_pos + n) > _chunk_size) _overflow(n);
void *p = (void *) (_chunk[_curr_chunk] + _chunk_pos);
_chunk_pos += n;
if(allocated() > _max)
_max = allocated();
return p;
}
/** The number of chunks currently allocated */
inline int nchunks() { return _nchunks; }
/** The size of every single chunk */
inline int chunksize() { return _chunk_size; }
/** The amount of memory currently allocated */
inline long long int allocated()
{ return (long long)_curr_chunk * (long long)_chunk_size + _chunk_pos; }
/** Pointer to the next free memory address */
inline void *current()
{ return (void *) (_chunk[_curr_chunk] + _chunk_pos); }
/** Pointer to the base of the current chunk still containing free memory */
inline void *current_base()
{ return (void *) (_chunk[_curr_chunk]); }
/** @name State Functions
* These functions, together with class chunk_alloc_state, support a
* stack-like allocation/deallocation strategy for situations where a lot of
* memory allocated between to points in computation may be released in
* one step (no memory has to be preserved in between these points)
*/
/*@{*/
/** Mark the current state of the chunk allocator */
inline void mark(chunk_alloc_state &s)
{ s.c = _curr_chunk; s.p = _chunk_pos; }
/** Release all memory allocated since this alloc state was marked */
inline void release(chunk_alloc_state &s)
{
_curr_chunk = s.c; _chunk_pos = s.p;
}
/*@}*/
/** Call this function when there is a good opportunity to release
* dispensable memory.
*/
void may_shrink();
/** Release all memory and reset all statistics */
void reset();
/** The maximum amount of memory (in bytes) allocated so far */
inline long long int max_usage()
{ return _max; }
inline long long int max_usage_mb()
{ return _max / (1024 * 1024); }
/** Reset maximum allocated size counter.
* Calling this method only makes sense after the total allocated memory
* may have shrunk.
*/
inline void reset_max_usage()
{ _max = 0; }
void print_check() ;
private:
/** number of bytes allocated in current chunk */
int _chunk_pos;
/** size of each chunk */
int _chunk_size;
/** index of chunk currently allocated from */
int _curr_chunk;
/** nr of currently allocated chunks */
int _nchunks;
/** vector of chunks of length MAX_CHUNKS */
char **_chunk;
/** max nr of bytes allocated so far */
long long int _max;
void _overflow(int n);
/** @name Statistics
* Collect statistics to enable shrinking
*/
/*@{*/
int _stats_chunk_sum;
int _stats_chunk_n;
/*@}*/
/** @name Core Memory Allocation */
/*@{*/
void _init_core(bool down, int chunksize);
void *_core_alloc(int size);
int _core_free(void *p, int size);
/*@}*/
/** Does the chunks in this allocator grow up or down ? */
bool _core_down;
#ifdef HAVE_MMAP
/** Pointers to the upper and lower allocation boundary of mmap(2) based core
* allocator.
*/
static char *_mmap_up_mark, *_mmap_down_mark;
/** Size of a memory page allocated by mmap(2) */
static size_t _pagesize;
friend bool is_p_addr(void *p);
#endif
};
#define t_alloc _t_alloc
/** Chunk allocator for temporarily needed memory. */
extern chunk_allocator t_alloc;
/** Chunk allocator for permanently needed memory. */
extern chunk_allocator p_alloc;
#if defined(HAVE_MMAP)
inline bool is_p_addr(void *p)
{
return p >= chunk_allocator::_mmap_down_mark;
}
#endif
#endif