00001 //================================================================================================== 00002 // Copyright (C) 2010 Brian Tietz sdbtietz at yahoo dot com 00003 // 00004 // This program is free software; you can redistribute it and/or modify it under the terms of the 00005 // GNU General Public License as published by the Free Software Foundation, version 2.0 of the 00006 // License. 00007 // 00008 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 00009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00010 // General Public License for more details. 00011 // 00012 // You should have received a copy of the GNU General Public License along with this program; if 00013 // not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00014 // 02110-1301, USA. 00015 // 00016 // For commercial software, the copyright holder (Brian Tietz, email sdbtietz at yahoo dot com) 00017 // reserves the right and is willing to waive the proprietary source code disclosure aspects of that 00018 // license as applied to the UT library in exchange for either substantial contributions to the 00019 // development of the UT library or other forms of compensation. Any such waiver must be 00020 // established in writing between the copyright holder and the commercial entity obtaining such a 00021 // waiver. 00022 //================================================================================================== 00023 00024 00025 #ifndef _UT_POOL_ALLOCATOR_H_ 00026 #define _UT_POOL_ALLOCATOR_H_ 00027 00028 00029 //================================================================================================== 00030 //=== System headers 00031 //================================================================================================== 00032 #include <stdlib.h> 00033 00034 00035 //================================================================================================== 00036 //=== Project headers 00037 //================================================================================================== 00038 #include "UTLists.h" 00039 #include "UTMutex.h" 00040 00041 00042 //================================================================================================== 00043 //=== Forward name declarations 00044 //================================================================================================== 00045 class Pool_t; 00046 00047 00048 //================================================================================================== 00049 //=== Types and constants 00050 //================================================================================================== 00051 const int c_pool_num_block_sizes = 26; 00052 struct PoolBlockSize_t 00053 { 00054 size_t max_block_size; 00055 int allocate_per_pool; 00056 }; 00057 00058 00059 //================================================================================================== 00060 class UT_EXPORT PoolAllocator_t 00061 //================================================================================================== 00070 { 00071 //---------------------------------------------------------------------------------------------- 00072 public: 00073 //---------------------------------------------------------------------------------------------- 00074 PoolAllocator_t(bool auto_thread_safe); 00078 00079 ~PoolAllocator_t(); 00081 00082 void* Allocate(size_t size); 00084 00085 void Release(void* block); 00087 00088 //---------------------------------------------------------------------------------------------- 00089 private: 00090 //---------------------------------------------------------------------------------------------- 00091 Pool_t* CreatePool(size_t block_size); 00092 void DeleteOldestPoolIfStale(); 00093 00094 //---------------------------------------------------------------------------------------------- 00095 private: 00096 //---------------------------------------------------------------------------------------------- 00097 PoolBlockSize_t m_pool_size_info[c_pool_num_block_sizes]; 00098 00099 Mutex_t* m_mutex; 00100 OwnedBTree_t< Pool_t, Pool_t* > m_all_pools_by_addr; 00101 BTree_t< Pool_t, size_t > m_avail_pools_by_size; 00102 LinkedList_t<Pool_t> m_delete_pools_by_age; 00103 BTree_t< Pool_t, size_t > m_delete_pools_by_size; 00104 }; 00105 00106 00107 // \cond DOXYGEN_DOCUMENT_NEVER 00108 00109 00110 //================================================================================================== 00111 class Pool_t 00112 //================================================================================================== 00113 : public BTreeNode_t< Pool_t, Pool_t* >, 00114 public BTreeNode_t< Pool_t, size_t >, 00115 public LinkedListNode_t<Pool_t> 00116 { 00117 //---------------------------------------------------------------------------------------------- 00118 public: 00119 //---------------------------------------------------------------------------------------------- 00120 void* operator new( size_t size, int capacity, size_t block_size ); 00121 Pool_t( int capacity, size_t block_size ); 00122 ~Pool_t(); 00123 void operator delete(void* malloced_block); 00124 00125 inline size_t BlockSize() const; 00126 inline int Capacity() const; 00127 inline bool AllBlocksAllocated() const; 00128 inline bool AllBlocksAvailable() const; 00129 bool Contains(byte* block) const; 00130 inline void InitDeleteCounter(int count); 00131 inline bool DecrementDeleteCounter(); 00132 byte* Allocate(); 00133 void Release(byte* block); 00134 00135 inline int Compare(Pool_t* address) const; 00136 inline operator Pool_t*() const; 00137 inline int Compare(size_t block_size) const; 00138 inline operator size_t() const; 00139 00140 //---------------------------------------------------------------------------------------------- 00141 private: 00142 //---------------------------------------------------------------------------------------------- 00143 size_t m_block_size; 00144 int m_capacity; 00145 uint32 m_avail_bitmap; 00146 uint32 m_avail_bitmap_when_all_avail; 00147 int m_delete_counter; 00148 }; 00149 00150 00151 00152 00153 //================================================================================================== 00154 //================================================================================================== 00155 //=== 00156 //=== Inline function implementations 00157 //=== 00158 //================================================================================================== 00159 //================================================================================================== 00160 inline size_t 00161 Pool_t::BlockSize() const 00162 { 00163 return m_block_size; 00164 } 00165 00166 00167 inline int 00168 Pool_t::Capacity() const 00169 { 00170 return m_capacity; 00171 } 00172 00173 00174 inline bool 00175 Pool_t::AllBlocksAllocated() const 00176 { 00177 return (m_avail_bitmap == 0); 00178 } 00179 00180 00181 inline bool 00182 Pool_t::AllBlocksAvailable() const 00183 { 00184 return (m_avail_bitmap == m_avail_bitmap_when_all_avail); 00185 } 00186 00187 00188 inline int 00189 Pool_t::Compare(Pool_t* address) const 00190 { 00191 // If this comes before other, Compare should return a negative number 00192 if(this < address) 00193 return -1; 00194 else if(this == address) 00195 return 0; 00196 return 1; 00197 } 00198 00199 00200 inline 00201 Pool_t::operator Pool_t*() const 00202 { 00203 return const_cast<Pool_t*>(this); 00204 } 00205 00206 00207 inline void 00208 Pool_t::InitDeleteCounter(int count) 00209 { 00210 m_delete_counter = count; 00211 } 00212 00213 00214 inline bool 00215 Pool_t::DecrementDeleteCounter() 00216 { 00217 assert(m_delete_counter > 0); 00218 m_delete_counter--; 00219 return (m_delete_counter == 0); 00220 } 00221 00222 00223 inline int 00224 Pool_t::Compare(size_t block_size) const 00225 { 00226 // If this comes before other, Compare should return a negative number 00227 if(m_block_size < block_size) 00228 return -1; 00229 else if(m_block_size == block_size) 00230 return 0; 00231 return 1; 00232 } 00233 00234 00235 inline 00236 Pool_t::operator size_t() const 00237 { 00238 return m_block_size; 00239 } 00240 00241 00242 // \endcond 00243 00244 #endif // _UT_POOL_ALLOCATOR_H_