00001 #ifndef BMALLOC__H__INCLUDED__
00002 #define BMALLOC__H__INCLUDED__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdlib.h>
00030 #include <new>
00031
00032 namespace bm
00033 {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 class block_allocator
00050 {
00051 public:
00052
00053
00054
00055
00056
00057 static bm::word_t* allocate(size_t n, const void *)
00058 {
00059 bm::word_t* ptr;
00060 #if defined(BMSSE2OPT) || defined(BMSSE42OPT)
00061 # ifdef _MSC_VER
00062 ptr = (bm::word_t*) ::_aligned_malloc(n * sizeof(bm::word_t), 16);
00063 #else
00064 ptr = (bm::word_t*) ::_mm_malloc(n * sizeof(bm::word_t), 16);
00065 # endif
00066
00067 #else
00068 ptr = (bm::word_t*) ::malloc(n * sizeof(bm::word_t));
00069 #endif
00070 if (!ptr)
00071 {
00072 throw std::bad_alloc();
00073 }
00074 return ptr;
00075 }
00076
00077
00078
00079
00080
00081 static void deallocate(bm::word_t* p, size_t)
00082 {
00083 #if defined(BMSSE2OPT) || defined(BMSSE42OPT)
00084 # ifdef _MSC_VER
00085 ::_aligned_free(p);
00086 #else
00087 ::_mm_free(p);
00088 # endif
00089
00090 #else
00091 ::free(p);
00092 #endif
00093 }
00094
00095 };
00096
00097
00098
00099
00100
00101
00102
00103
00104 class ptr_allocator
00105 {
00106 public:
00107
00108
00109
00110
00111
00112 static void* allocate(size_t n, const void *)
00113 {
00114 void* ptr = ::malloc(n * sizeof(void*));
00115 if (!ptr)
00116 {
00117 throw std::bad_alloc();
00118 }
00119 return ptr;
00120 }
00121
00122
00123
00124
00125
00126 static void deallocate(void* p, size_t)
00127 {
00128 ::free(p);
00129 }
00130 };
00131
00132
00133
00134
00135
00136
00137
00138
00139 template<class BA, class PA> class mem_alloc
00140 {
00141 public:
00142 typedef BA block_allocator_type;
00143 typedef PA ptr_allocator_type;
00144
00145 public:
00146
00147 mem_alloc(const BA& block_alloc = BA(), const PA& ptr_alloc = PA())
00148 : block_alloc_(block_alloc),
00149 ptr_alloc_(ptr_alloc)
00150 {}
00151
00152
00153
00154 block_allocator_type get_block_allocator() const
00155 {
00156 return BA(block_alloc_);
00157 }
00158
00159
00160
00161 ptr_allocator_type get_ptr_allocator() const
00162 {
00163 return PA(block_alloc_);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173 bm::word_t* alloc_bit_block(unsigned alloc_factor = 1)
00174 {
00175 return block_alloc_.allocate(bm::set_block_size * alloc_factor, 0);
00176 }
00177
00178
00179
00180 void free_bit_block(bm::word_t* block, unsigned alloc_factor = 1)
00181 {
00182 if (IS_VALID_ADDR(block))
00183 block_alloc_.deallocate(block, bm::set_block_size * alloc_factor);
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 bm::gap_word_t* alloc_gap_block(unsigned level,
00194 const gap_word_t* glevel_len)
00195 {
00196 BM_ASSERT(level < bm::gap_levels);
00197 unsigned len =
00198 glevel_len[level] / (sizeof(bm::word_t) / sizeof(gap_word_t));
00199
00200 return (bm::gap_word_t*)block_alloc_.allocate(len, 0);
00201 }
00202
00203
00204
00205 void free_gap_block(bm::gap_word_t* block,
00206 const gap_word_t* glevel_len)
00207 {
00208 BM_ASSERT(IS_VALID_ADDR((bm::word_t*)block));
00209
00210 unsigned len = gap_capacity(block, glevel_len);
00211 len /= sizeof(bm::word_t) / sizeof(bm::gap_word_t);
00212 block_alloc_.deallocate((bm::word_t*)block, len);
00213 }
00214
00215
00216
00217 void* alloc_ptr(unsigned size = bm::set_array_size)
00218 {
00219 return ptr_alloc_.allocate(size, 0);
00220 }
00221
00222
00223
00224 void free_ptr(void* p, unsigned size = bm::set_array_size)
00225 {
00226 if (p)
00227 ptr_alloc_.deallocate(p, size);
00228 }
00229 private:
00230 BA block_alloc_;
00231 PA ptr_alloc_;
00232 };
00233
00234 typedef mem_alloc<block_allocator, ptr_allocator> standard_allocator;
00235
00236
00237
00238
00239 }
00240
00241
00242 #endif