![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved. 00003 00004 Redistribution and use in source and binary forms, with or without 00005 modification, are permitted provided that the following conditions are met: 00006 00007 * Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, 00010 this list of conditions and the following disclaimer in the documentation 00011 and/or other materials provided with the distribution. 00012 * Neither the name of LibCat nor the names of its contributors may be used 00013 to endorse or promote products derived from this software without 00014 specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00019 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00020 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00021 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00022 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00023 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00024 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00025 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00026 POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 #ifndef CAT_REGION_ALLOCATOR_HPP 00030 #define CAT_REGION_ALLOCATOR_HPP 00031 00032 #include <cat/Singleton.hpp> 00033 #include <memory> 00034 #include <xstring> 00035 #include <sstream> 00036 00037 namespace cat { 00038 00039 00040 // A region-based allocator that is lock-free, supporting 00041 // a range of allocation block sizes that are pre-allocated 00042 // in a pre-determined way, tuned to the application. 00043 class RegionAllocator : public Singleton<RegionAllocator> 00044 { 00045 CAT_SINGLETON(RegionAllocator); 00046 00047 protected: 00048 struct RegionInfoHead 00049 { 00050 u32 next_bitmap_entry; 00051 }; 00052 00053 struct RegionInfo : public RegionInfoHead 00054 { 00055 volatile u32 bitmap[1]; 00056 }; 00057 00058 // 64, 128, 256, 512, 1024, 2048 only 00059 static const u32 REGION_COUNT = 6; 00060 static const u32 BLOCK_SIZE[REGION_COUNT]; 00061 00062 u32 bytes_overall; 00063 u32 blocks_per_region[REGION_COUNT]; 00064 u32 bitmap_dwords[REGION_COUNT]; 00065 u8 *regions[REGION_COUNT]; 00066 RegionInfo *region_info[REGION_COUNT]; 00067 00068 //u32 errors; 00069 00070 public: 00071 bool Valid(); 00072 00073 void Shutdown(); 00074 00075 public: 00076 void *Acquire(u32 bytes); 00077 void *Resize(void *ptr, u32 bytes); 00078 void Release(void *ptr); 00079 00080 template<class T> 00081 CAT_INLINE void Delete(T *ptr) 00082 { 00083 ptr->~T(); 00084 Release(ptr); 00085 } 00086 00087 // Acquires a buffer from the allocator that is the size of the type. 00088 // It further allocates a number of extra bytes beyond the end of the buffer. 00089 // Release the buffer with: 00090 // RegionAllocator::ii->Release(ptr); 00091 template<class T> T *AcquireBuffer(u32 extra_bytes = 0) 00092 { 00093 return reinterpret_cast<T*>( Acquire(sizeof(T) + extra_bytes) ); 00094 } 00095 }; 00096 00097 // Use STLRegionAllocator in place of the standard STL allocator 00098 // to make use of the RegionAllocator in STL types. Some common 00099 // usage typedefs follow this class definition below. 00100 template<typename T> 00101 class STLRegionAllocator 00102 { 00103 public: 00104 typedef size_t size_type; 00105 typedef size_t difference_type; 00106 typedef T *pointer; 00107 typedef const T *const_pointer; 00108 typedef T &reference; 00109 typedef const T &const_reference; 00110 typedef T value_type; 00111 00112 template<typename S> 00113 struct rebind 00114 { 00115 typedef STLRegionAllocator<S> other; 00116 }; 00117 00118 pointer address(reference X) const 00119 { 00120 return &X; 00121 } 00122 00123 const_pointer address(const_reference X) const 00124 { 00125 return &X; 00126 } 00127 00128 STLRegionAllocator() throw () 00129 { 00130 } 00131 00132 template<typename S> 00133 STLRegionAllocator(const STLRegionAllocator<S> &cp) throw () 00134 { 00135 } 00136 00137 template<typename S> 00138 STLRegionAllocator<T> &operator=(const STLRegionAllocator<S> &cp) throw () 00139 { 00140 return *this; 00141 } 00142 00143 pointer allocate(size_type Count, const void *Hint = 0) 00144 { 00145 return (pointer)RegionAllocator::ii->Acquire((u32)Count * sizeof(T)); 00146 } 00147 00148 void deallocate(pointer Ptr, size_type Count) 00149 { 00150 RegionAllocator::ii->Release(Ptr); 00151 } 00152 00153 void construct(pointer Ptr, const T &Val) 00154 { 00155 std::_Construct(Ptr, Val); 00156 } 00157 00158 void destroy(pointer Ptr) 00159 { 00160 std::_Destroy(Ptr); 00161 } 00162 00163 size_type max_size() const 00164 { 00165 return 0x00FFFFFF; 00166 } 00167 00168 template<typename S> 00169 bool operator==(STLRegionAllocator <S> const &) const throw() 00170 { 00171 return true; 00172 } 00173 00174 template<typename S> 00175 bool operator!=(STLRegionAllocator <S> const &) const throw() 00176 { 00177 return false; 00178 } 00179 }; 00180 00181 // Common usage typedefs for using RegionAllocator as the STL allocator 00182 typedef std::basic_ostringstream<char, std::char_traits<char>, STLRegionAllocator<char> > region_ostringstream; 00183 typedef std::basic_string<char, std::char_traits<char>, STLRegionAllocator<char> > region_string; 00184 00185 00186 } // namespace cat 00187 00188 // Provide placement new constructor and delete pair to allow for 00189 // an easy syntax to create objects from the RegionAllocator: 00190 // T *a = new (RegionAllocator::ii) T(); 00191 // The object can be freed with: 00192 // RegionAllocator::ii->Delete(a); 00193 // Which insures that the destructor is called before freeing memory 00194 inline void *operator new(size_t bytes, cat::RegionAllocator *allocator) 00195 { 00196 return allocator->Acquire((cat::u32)bytes); 00197 } 00198 00199 inline void operator delete(void *ptr, cat::RegionAllocator *allocator) 00200 { 00201 allocator->Release(ptr); 00202 } 00203 00204 00205 #endif // CAT_REGION_ALLOCATOR_HPP
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.