-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsli_allocator.h
178 lines (144 loc) · 4.16 KB
/
sli_allocator.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
/*
* allocator.h
*
* This file is part of NEST
*
* Copyright (C) 2004 by
* The NEST Initiative
*
* See the file AUTHORS for details.
*
* Permission is granted to compile and modify
* this file for non-commercial use.
* See the file LICENSE for details.
*
*/
#ifndef SLI_ALLOCATOR_H
#define SLI_ALLOCATOR_H
#include <cassert>
#include <cstdlib>
#include <string>
namespace sli3 {
/**
* @addtogroup MemoryManagement Memory management
* Classes which are involved in Memory management.
*/
/**
* @defgroup PoolAllocator Pool allocator
* The pool allocator is specialized for creating many small identical objects.
* @ingroup MemoryManagement
*/
/**
* pool is a specialized allocator class for many identical small
* objects. It targets a performance close to the optimal performance
* which is achieved by allocating all needed objects at once.
* @ingroup MemoryManagement
* @ingroup PoolAllocator
*/
class pool
{
struct link { link *next; };
class chunk
{
const size_t csize;
chunk(const chunk&); //!< not implemented
chunk& operator=(const chunk&); //!< not implemented
public:
chunk *next;
char *mem;
chunk(size_t s)
:csize(s),
mem(new char[csize])
{}
~chunk()
{
delete [] mem;
mem=NULL;
}
size_t size(void)
{ return csize;}
};
size_t initial_block_size;
size_t growth_factor;
size_t block_size; //!< number of elements per chunk
size_t el_size; //!< sizeof an element
size_t instantiations; //!< number of instatiated elements
size_t total; //!< total number of allocated elements
size_t capacity; //!< number of free elements
chunk *chunks; //!< linked list of memory chunks
link *head; //!< head of free list
bool initialized_; //!< True if the pool is initialized.
void grow(size_t); //!< make pool larger by n elements
void grow(); //!< make pool larger
public:
/** Create pool for objects of size n. Initial is the inital allocation
* block size, i.e. the number of objects per block.
* growth is the factor by which the allocations block increases after
* each growth.
*/
pool();
pool(const pool &);
pool& operator=(const pool&);
pool(size_t n, size_t initial=100, size_t growth=1);
void init(size_t n, size_t initial=100, size_t growth=1);
~pool(); //!< deallocate ALL memory
/** Increase the pools capacity (free slots) to at least n.
Reserve() ensures that the pool has at least n empty slots,
i.e., that the pool can store at least n additional elements
before more memory needs to be allocated from the operating
system.
@note The semantics of pool::reserve(n) differ from the semantics
of reserve(n) for STL containers: for STL containers, n is the total
number of elements after the reserve() call, while for pool it is the
number of @b free @b elements.
@todo Adapt the semantics of capacity() and reserve() to STL semantics.
*/
void reserve(size_t n);
size_t available(void) const
{ return total-instantiations;}
inline void *alloc(void); //!< allocate one element
inline void free(void* p); //!< put element back into the pool
size_t size_of(void) const
{ return el_size;}
inline size_t get_el_size() const;
inline size_t get_instantiations() const;
inline size_t get_total() const;
};
inline
void * pool::alloc(void)
{
if(head==0)
{
grow(block_size);
block_size *= growth_factor;
}
link *p=head;
head = head->next;
++instantiations;
return p;
}
inline
void pool::free(void *elp)
{
link *p= static_cast<link *>(elp);
p->next= head;
head = p;
--instantiations;
}
inline
size_t pool::get_el_size() const
{
return el_size;
}
inline
size_t pool::get_instantiations() const
{
return instantiations;
}
inline
size_t pool::get_total() const
{
return total;
}
}
#endif