dlvhex
2.5.0
|
00001 #ifndef BMALLOC__H__INCLUDED__ 00002 #define BMALLOC__H__INCLUDED__ 00003 /* 00004 Copyright(c) 2002-2009 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com) 00005 00006 Permission is hereby granted, free of charge, to any person 00007 obtaining a copy of this software and associated documentation 00008 files (the "Software"), to deal in the Software without restriction, 00009 including without limitation the rights to use, copy, modify, merge, 00010 publish, distribute, sublicense, and/or sell copies of the Software, 00011 and to permit persons to whom the Software is furnished to do so, 00012 subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included 00015 in all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00018 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 00019 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00020 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00021 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00022 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00023 OTHER DEALINGS IN THE SOFTWARE. 00024 00025 For more information please visit: http://bmagic.sourceforge.net 00026 00027 */ 00028 00029 #include <stdlib.h> 00030 #include <new> 00031 00032 namespace bm 00033 { 00034 00035 00049 class block_allocator 00050 { 00051 public: 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 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 00104 class ptr_allocator 00105 { 00106 public: 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 00126 static void deallocate(void* p, size_t) 00127 { 00128 ::free(p); 00129 } 00130 }; 00131 00132 // ------------------------------------------------------------------------- 00133 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 00154 block_allocator_type get_block_allocator() const 00155 { 00156 return BA(block_alloc_); 00157 } 00158 00161 ptr_allocator_type get_ptr_allocator() const 00162 { 00163 return PA(block_alloc_); 00164 } 00165 00166 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 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 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 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 00217 void* alloc_ptr(unsigned size = bm::set_array_size) 00218 { 00219 return ptr_alloc_.allocate(size, 0); 00220 } 00221 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 00239 } // namespace bm 00240 00241 00242 #endif