23 protected: |
23 protected: |
24 OldMemoryPoolBase(const char *name, uint max_blocks, uint block_size_bits, uint item_size, |
24 OldMemoryPoolBase(const char *name, uint max_blocks, uint block_size_bits, uint item_size, |
25 OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) : |
25 OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) : |
26 name(name), max_blocks(max_blocks), block_size_bits(block_size_bits), |
26 name(name), max_blocks(max_blocks), block_size_bits(block_size_bits), |
27 new_block_proc(new_block_proc), clean_block_proc(clean_block_proc), current_blocks(0), |
27 new_block_proc(new_block_proc), clean_block_proc(clean_block_proc), current_blocks(0), |
28 total_items(0), item_size(item_size), first_free_index(0), blocks(NULL) {} |
28 total_items(0), cleaning_pool(false), item_size(item_size), first_free_index(0), blocks(NULL) {} |
29 |
29 |
30 const char* name; ///< Name of the pool (just for debugging) |
30 const char* name; ///< Name of the pool (just for debugging) |
31 |
31 |
32 const uint max_blocks; ///< The max amount of blocks this pool can have |
32 const uint max_blocks; ///< The max amount of blocks this pool can have |
33 const uint block_size_bits; ///< The size of each block in bits |
33 const uint block_size_bits; ///< The size of each block in bits |
38 OldMemoryPoolCleanBlock *clean_block_proc; |
38 OldMemoryPoolCleanBlock *clean_block_proc; |
39 |
39 |
40 uint current_blocks; ///< How many blocks we have in our pool |
40 uint current_blocks; ///< How many blocks we have in our pool |
41 uint total_items; ///< How many items we now have in this pool |
41 uint total_items; ///< How many items we now have in this pool |
42 |
42 |
|
43 bool cleaning_pool; ///< Are we currently cleaning the pool? |
43 public: |
44 public: |
44 const uint item_size; ///< How many bytes one block is |
45 const uint item_size; ///< How many bytes one block is |
45 uint first_free_index; ///< The index of the first free pool item in this pool |
46 uint first_free_index; ///< The index of the first free pool item in this pool |
46 byte **blocks; ///< An array of blocks (one block hold all the items) |
47 byte **blocks; ///< An array of blocks (one block hold all the items) |
47 |
48 |
119 } |
129 } |
120 } |
130 } |
121 |
131 |
122 /** |
132 /** |
123 * Generic function to free a new block in a pool. |
133 * Generic function to free a new block in a pool. |
124 * This function uses QuickFree that is intended to only free memory that would be lost if the pool is freed. |
|
125 * @param start_item the first item that needs to be cleaned |
134 * @param start_item the first item that needs to be cleaned |
126 * @param end_item the last item that needs to be cleaned |
135 * @param end_item the last item that needs to be cleaned |
127 */ |
136 */ |
128 template <typename T, OldMemoryPool<T> *Tpool> |
137 template <typename T, OldMemoryPool<T> *Tpool> |
129 static void PoolCleanBlock(uint start_item, uint end_item) |
138 static void PoolCleanBlock(uint start_item, uint end_item) |
130 { |
139 { |
131 for (uint i = start_item; i <= end_item; i++) { |
140 for (uint i = start_item; i <= end_item; i++) { |
132 T *t = Tpool->Get(i); |
141 T *t = Tpool->Get(i); |
133 if (t->IsValid()) { |
142 delete t; |
134 t->QuickFree(); |
|
135 } |
|
136 } |
143 } |
137 } |
144 } |
138 |
145 |
139 |
146 |
140 /** |
147 /** |
155 { |
162 { |
156 if (this->index < Tpool->first_free_index) Tpool->first_free_index = this->index; |
163 if (this->index < Tpool->first_free_index) Tpool->first_free_index = this->index; |
157 } |
164 } |
158 |
165 |
159 /** |
166 /** |
160 * Called on each object when the pool is being destroyed, so one |
|
161 * can free allocated memory without the need for freeing for |
|
162 * example orders. |
|
163 */ |
|
164 virtual void QuickFree() |
|
165 { |
|
166 } |
|
167 |
|
168 /** |
|
169 * An overriden version of new that allocates memory on the pool. |
167 * An overriden version of new that allocates memory on the pool. |
170 * @param size the size of the variable (unused) |
168 * @param size the size of the variable (unused) |
171 * @return the memory that is 'allocated' |
169 * @return the memory that is 'allocated' |
172 */ |
170 */ |
173 void *operator new(size_t size) |
171 void *operator new(size_t size) |
239 protected: |
237 protected: |
240 /** |
238 /** |
241 * Allocate a pool item; possibly allocate a new block in the pool. |
239 * Allocate a pool item; possibly allocate a new block in the pool. |
242 * @return the allocated pool item (or NULL when the pool is full). |
240 * @return the allocated pool item (or NULL when the pool is full). |
243 */ |
241 */ |
244 static T *AllocateRaw() |
242 static inline T *AllocateRaw() |
245 { |
243 { |
246 return AllocateRaw(Tpool->first_free_index); |
244 return AllocateRaw(Tpool->first_free_index); |
247 } |
245 } |
248 |
246 |
249 /** |
247 /** |
250 * Allocate a pool item; possibly allocate a new block in the pool. |
248 * Allocate a pool item; possibly allocate a new block in the pool. |
251 * @param first the first pool item to start searching |
249 * @param first the first pool item to start searching |
252 * @return the allocated pool item (or NULL when the pool is full). |
250 * @return the allocated pool item (or NULL when the pool is full). |
253 */ |
251 */ |
254 static T *AllocateRaw(uint &first) |
252 static inline T *AllocateRaw(uint &first) |
255 { |
253 { |
256 uint last_minus_one = Tpool->GetSize() - 1; |
254 uint last_minus_one = Tpool->GetSize() - 1; |
257 |
255 |
258 for (T *t = Tpool->Get(first); t != NULL; t = (t->index < last_minus_one) ? Tpool->Get(t->index + 1U) : NULL) { |
256 for (T *t = Tpool->Get(first); t != NULL; t = (t->index < last_minus_one) ? Tpool->Get(t->index + 1U) : NULL) { |
259 if (!t->IsValid()) { |
257 if (!t->IsValid()) { |
269 /* Check if we can add a block to the pool */ |
267 /* Check if we can add a block to the pool */ |
270 if (Tpool->AddBlockToPool()) return AllocateRaw(first); |
268 if (Tpool->AddBlockToPool()) return AllocateRaw(first); |
271 |
269 |
272 return NULL; |
270 return NULL; |
273 } |
271 } |
|
272 |
|
273 /** |
|
274 * Are we cleaning this pool? |
|
275 * @return true if we are |
|
276 */ |
|
277 static inline bool CleaningPool() |
|
278 { |
|
279 return Tpool->CleaningPool(); |
|
280 } |
274 }; |
281 }; |
275 |
282 |
276 |
283 |
277 #define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ |
284 #define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ |
278 enum { \ |
285 enum { \ |