89
87
under this License.
92
92
#ident "Copyright (c) 2007-2013 Tokutek Inc. All rights reserved."
93
93
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
95
/* We have too many memory management tricks:
96
* memarena (this code) is for a collection of objects that cannot be moved.
97
* The pattern is allocate more and more stuff.
98
* Don't free items as you go.
99
* Free all the items at once.
100
* Then reuse the same buffer again.
101
* Allocated objects never move.
102
* A memarena (as currently implemented) is not suitable for interprocess memory sharing. No reason it couldn't be made to work though.
96
* A memarena is used to efficiently store a collection of objects that never move
97
* The pattern is allocate more and more stuff and free all of the items at once.
98
* The underlying memory will store 1 or more objects per chunk. Each chunk is
99
* contiguously laid out in memory but chunks are not necessarily contiguous with
107
typedef struct memarena *MEMARENA;
109
MEMARENA toku_memarena_create_presized (size_t initial_size);
110
// Effect: Create a memarena with initial size. In case of ENOMEM, aborts.
112
MEMARENA toku_memarena_create (void);
113
// Effect: Create a memarena with default initial size. In case of ENOMEM, aborts.
115
void toku_memarena_clear (MEMARENA ma);
116
// Effect: Reset the internal state so that the allocated memory can be used again.
118
void* toku_memarena_malloc (MEMARENA ma, size_t size);
119
// Effect: Allocate some memory. The returned value remains valid until the memarena is cleared or closed.
120
// In case of ENOMEM, aborts.
122
void *toku_memarena_memdup (MEMARENA ma, const void *v, size_t len);
124
void toku_memarena_destroy(MEMARENA *ma);
126
void toku_memarena_move_buffers(MEMARENA dest, MEMARENA source);
127
// Effect: Move all the memory from SOURCE into DEST. When SOURCE is closed the memory won't be freed. When DEST is closed, the memory will be freed. (Unless DEST moves its memory to another memarena...)
129
size_t toku_memarena_total_memory_size (MEMARENA);
130
// Effect: Calculate the amount of memory used by a memory arena.
132
size_t toku_memarena_total_size_in_use (MEMARENA);
134
size_t toku_memarena_total_footprint (MEMARENA);
105
_current_chunk(arena_chunk()),
106
_other_chunks(nullptr),
108
_size_of_other_chunks(0),
109
_footprint_of_other_chunks(0) {
112
// Effect: Create a memarena with the specified initial size
113
void create(size_t initial_size);
117
// Effect: Allocate some memory. The returned value remains valid until the memarena is cleared or closed.
118
// In case of ENOMEM, aborts.
119
void *malloc_from_arena(size_t size);
121
// Effect: Move all the memory from this memarena into DEST.
122
// When SOURCE is closed the memory won't be freed.
123
// When DEST is closed, the memory will be freed, unless DEST moves its memory to another memarena...
124
void move_memory(memarena *dest);
126
// Effect: Calculate the amount of memory used by a memory arena.
127
size_t total_memory_size(void) const;
129
// Effect: Calculate the used space of the memory arena (ie: excludes unused space)
130
size_t total_size_in_use(void) const;
132
// Effect: Calculate the amount of memory used, according to toku_memory_footprint(),
133
// which is a more expensive but more accurate count of memory used.
134
size_t total_footprint(void) const;
136
// iterator over the underlying chunks that store objects in the memarena.
137
// a chunk is represented by a pointer to const memory and a usable byte count.
138
class chunk_iterator {
140
chunk_iterator(const memarena *ma) :
141
_ma(ma), _chunk_idx(-1) {
144
// returns: base pointer to the current chunk
145
// *used set to the number of usable bytes
146
// if more() is false, returns nullptr and *used = 0
147
const void *current(size_t *used) const;
149
// requires: more() is true
155
// -1 represents the 'initial' chunk in a memarena, ie: ma->_current_chunk
156
// >= 0 represents the i'th chunk in the ma->_other_chunks array
163
arena_chunk() : buf(nullptr), used(0), size(0) { }
169
struct arena_chunk _current_chunk;
170
struct arena_chunk *_other_chunks;
172
size_t _size_of_other_chunks; // the buf_size of all the other chunks.
173
size_t _footprint_of_other_chunks; // the footprint of all the other chunks.
175
friend class memarena_unit_test;