/// return all chunks to OS 48 49 bool operator == (const bitmap_fixed_size_allocator&) const; 50 bool operator != (const bitmap_fixed_size_allocator&) const; 51 52 protected: 53 union object { index_type idx; char pad[1U]; }; /// metadata of a block 54 union chunk { size_type map; char pad[1U]; }; /// metadata of a chunk 55 56 static const size_type FREE = static_cast(-1); 57 58 static chunk* chk_hd; /// only one chunk reserved 59 size_type blk_sz; 60 size_type sz_lmt; /// threshold of block (maximum block) 61 62 void mark_bit(size_type&, index_type) const; /// reserved one block by set 0 63 void clear_bit(size_type&, index_type) const; /// released one block by set 1 64 index_type find_fbit(size_type) const; /// get free bit in map 65 object* get_fblk(chunk*); /// get a free block in chunk 66 object* chunk_alloc(); /// allocate a chunk from OS 67 68 private: 69 /// prevent some silly operations 70 bitmap_fixed_size_allocator(const bitmap_fixed_size_allocator&); 71 bitmap_fixed_size_allocator& operator =(const bitmap_fixed_size_allocator); 72 }; 73 74 75 typename bitmap_fixed_size_allocator::chunk* bitmap_fixed_size_allocator::chk_hd = 0; 76 77 /// Only one allocator at same scope, so it is always equal if a comparison necessary. 78 79 bool bitmap_fixed_size_allocator::operator ==(const bitmap_fixed_size_allocator&) const 80 { 81 return true; 82 } 83 84 85 bool bitmap_fixed_size_allocator::operator !=(const bitmap_fixed_size_allocator&) const 86 { 87 return false; 88 } 89 90 bitmap_fixed_size_allocator::bitmap_fixed_size_allocator(size_type block_size, 91 size_type max_block_size) : 92 default_mutex(), 93 blk_sz(block_size + sizeof(object)), 94 sz_lmt(max_block_size + sizeof(object)) 95 {} 96 97 98 bitmap_fixed_size_allocator::~bitmap_fixed_size_allocator() 99 { 100 std::free(chk_hd); 101 } 102 103 inline void bitmap_fixed_size_allocator::mark_bit(size_type& map, index_type idx) const 104 { 105 map &= ~(1U << idx); 106 } /// set 0 107 108 inline void bitmap_fixed_size_allocator::clear_bit(size_type& map, index_type idx) const 109 { 110 map |= (1U << idx); 111 } /// set 1 112 113 inline void* bitmap_fixed_size_allocator::allocate() 114 { 115 void* ptr = 0; 116 if(sz_lmt < blk_sz) 117 ptr = std::malloc(blk_sz - sizeof(object)); 118 else 119 { 120 chunk* cptr = chk_hd; 121 if(0 == cptr || 0 == cptr->map) 122 ptr = chunk_alloc(); 123 else 124 ptr = get_fblk(cptr); 125 } 126 return ptr; 127 } 128 129 inline void bitmap_fixed_size_allocator::deallocate(void* p) 130 { 131 if(0 == p) 132 return; 133 if(sz_lmt < blk_sz) 134 std::free(p); 135 else 136 { 137 object* bptr = (object*)p - 1U; 138 index_type bidx = bptr->idx; 139 chunk* cptr = (chunk*)((char*)bptr - bidx * blk_sz) - 1U; 140 clear_bit(cptr->map, bidx); 141 if(FREE == cptr->map && cptr != chk_hd) 142 std::free(cptr); 143 } 144 } 145 146 inline typename bitmap_fixed_size_allocator::index_type 147 bitmap_fixed_size_allocator::find_fbit(size_type map) const 148 { 149 index_type idx; 150 #if (defined(__GNUC |