Bcp 1.4.4
Loading...
Searching...
No Matches
BCP_mempool.hpp
Go to the documentation of this file.
1// Copyright (C) 2000, International Business Machines
2// Corporation and others. All Rights Reserved.
3#ifndef _BCP_MEMPOOL_H
4#define _BCP_MEMPOOL_H
5
6// #define BCP_MEMPOOL_SAVE_BLOCKHEADS
7
9private:
10 const size_t BLOCK_SIZE;
11 size_t entry_size;
12 void ** first_free;
13#ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
14 void *** block_heads;
15 size_t block_num;
16 size_t max_block_num;
17#endif
18public:
19 // Create an allocator for objects of size n
20 BCP_MemPool(const size_t n, const size_t bl_size = 1023) :
21 BLOCK_SIZE(bl_size), entry_size(n), first_free(0)
22#ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
23 , block_heads(0), block_num(0), max_block_num(0)
24#endif
25 {}
26
27 // Allocate enough memory for one object;
28 inline void * alloc(size_t n) {
29 if (n != entry_size)
30 return ::operator new(n);
31 void ** p = first_free;
32 if (p) {
33 first_free = static_cast<void **>(*p);
34 } else {
35 // create the new block and save its head
36 const size_t ptr_in_entry = entry_size/sizeof(void**) +
37 ((entry_size % sizeof(void **)) == 0 ? 0 : 1);
38 const size_t dist = ptr_in_entry * sizeof(void **);
39 void ** block = static_cast<void**>(::operator new(BLOCK_SIZE*dist));
40#ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
41 // see if we can record another block head. If not, then resize
42 // block_heads
43 if (max_block_num == block_num) {
44 max_block_num = 1.2 * block_num + 10;
45 const void *** old_block_heads = block_heads;
46 block_heads = static_cast<void ***>(::operator new(max_block_num));
47 for (size_t i = 0; i < block_num; ++i)
48 block_heads[i] = old_block_heads[i];
49 ::operator delete(old_block_heads);
50 }
51 // save the new block
52 block_heads[block_num++] = block;
53#endif
54 // link the entries in the new block together. skip the zeroth
55 // element, that'll be returned to the caller.
56 for (size_t i = 1; i < BLOCK_SIZE-1; ++i)
57 block[i*ptr_in_entry] =
58 static_cast<void*>(block + ((i+1)*ptr_in_entry));
59 // terminate the linked list with a null pointer
60 block[(BLOCK_SIZE-1)*ptr_in_entry] = 0;
61 p = block;
62 first_free = block + ptr_in_entry;
63 }
64 return static_cast<void*>(p);
65 }
66
67 // Return to the pool the memory pointed to by p;
68 inline void free(void *p, size_t n) {
69 if (p == 0) return;
70 if (n != entry_size) {
71 ::operator delete(p);
72 return;
73 }
74 void** pp = static_cast<void**>(p);
75 *pp = static_cast<void*>(first_free);
76 first_free = pp;
77 }
78 // Deallocate all memory in the pool
80#ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
81 for (size_t i = 0; i < block_num; ++i) {
82 ::operator delete(block_heads[i]);
83 }
84 ::operator delete(block_heads);
85#endif
86 }
87};
88
89#endif
BCP_MemPool(const size_t n, const size_t bl_size=1023)
void free(void *p, size_t n)
void * alloc(size_t n)