![]() |
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_ALIGNED_ALLOC_HPP 00030 #define CAT_ALIGNED_ALLOC_HPP 00031 00032 #include <cat/Platform.hpp> 00033 00034 #include <cstddef> // size_t 00035 #include <vector> // std::_Construct and std::_Destroy 00036 00037 00038 namespace cat { 00039 00040 00041 // Small to medium -size aligned heap allocator 00042 class Aligned 00043 { 00044 public: 00045 CAT_INLINE Aligned() {} 00046 00047 // Acquires memory aligned to a CPU cache-line byte boundary from the heap 00048 static void *Acquire(u32 bytes); 00049 00050 // Resizes an aligned pointer 00051 static void *Resize(void *ptr, u32 bytes); 00052 00053 // Release an aligned pointer 00054 static void Release(void *ptr); 00055 00056 template<class T> 00057 static inline void Delete(T *ptr) 00058 { 00059 ptr->~T(); 00060 Release(ptr); 00061 } 00062 00063 static Aligned ii; 00064 }; 00065 00066 // Use STLAlignedAllocator in place of the standard STL allocator 00067 // to make use of the Aligned in STL types. 00068 template<typename T> 00069 class STLAlignedAllocator 00070 { 00071 public: 00072 typedef std::size_t size_type; 00073 typedef std::size_t difference_type; 00074 typedef T *pointer; 00075 typedef const T *const_pointer; 00076 typedef T &reference; 00077 typedef const T &const_reference; 00078 typedef T value_type; 00079 00080 template<typename S> 00081 struct rebind 00082 { 00083 typedef STLAlignedAllocator<S> other; 00084 }; 00085 00086 pointer address(reference X) const 00087 { 00088 return &X; 00089 } 00090 00091 const_pointer address(const_reference X) const 00092 { 00093 return &X; 00094 } 00095 00096 STLAlignedAllocator() throw () 00097 { 00098 } 00099 00100 template<typename S> 00101 STLAlignedAllocator(const STLAlignedAllocator<S> &cp) throw () 00102 { 00103 } 00104 00105 template<typename S> 00106 STLAlignedAllocator<T> &operator=(const STLAlignedAllocator<S> &cp) throw () 00107 { 00108 return *this; 00109 } 00110 00111 pointer allocate(size_type Count, const void *Hint = 0) 00112 { 00113 return (pointer)Aligned::Acquire((u32)Count * sizeof(T)); 00114 } 00115 00116 void deallocate(pointer Ptr, size_type Count) 00117 { 00118 Aligned::Release(Ptr); 00119 } 00120 00121 void construct(pointer Ptr, const T &Val) 00122 { 00123 std::_Construct(Ptr, Val); 00124 } 00125 00126 void destroy(pointer Ptr) 00127 { 00128 std::_Destroy(Ptr); 00129 } 00130 00131 size_type max_size() const 00132 { 00133 return 0x00FFFFFF; 00134 } 00135 00136 template<typename S> 00137 bool operator==(STLAlignedAllocator <S> const &) const throw() 00138 { 00139 return true; 00140 } 00141 00142 template<typename S> 00143 bool operator!=(STLAlignedAllocator <S> const &) const throw() 00144 { 00145 return false; 00146 } 00147 }; 00148 00149 00150 // Large-size aligned heap allocator 00151 class LargeAligned 00152 { 00153 public: 00154 // Acquires memory aligned to a CPU cache-line byte boundary from the heap 00155 static void *Acquire(u32 bytes); 00156 00157 // Release an aligned pointer 00158 static void Release(void *ptr); 00159 }; 00160 00161 // Use STLAlignedAllocator in place of the standard STL allocator 00162 // to make use of the Aligned in STL types. 00163 template<typename T> 00164 class STLLargeAlignedAllocator 00165 { 00166 public: 00167 typedef std::size_t size_type; 00168 typedef std::size_t difference_type; 00169 typedef T *pointer; 00170 typedef const T *const_pointer; 00171 typedef T &reference; 00172 typedef const T &const_reference; 00173 typedef T value_type; 00174 00175 template<typename S> 00176 struct rebind 00177 { 00178 typedef STLLargeAlignedAllocator<S> other; 00179 }; 00180 00181 pointer address(reference X) const 00182 { 00183 return &X; 00184 } 00185 00186 const_pointer address(const_reference X) const 00187 { 00188 return &X; 00189 } 00190 00191 STLLargeAlignedAllocator() throw () 00192 { 00193 } 00194 00195 template<typename S> 00196 STLLargeAlignedAllocator(const STLLargeAlignedAllocator<S> &cp) throw () 00197 { 00198 } 00199 00200 template<typename S> 00201 STLLargeAlignedAllocator<T> &operator=(const STLLargeAlignedAllocator<S> &cp) throw () 00202 { 00203 return *this; 00204 } 00205 00206 pointer allocate(size_type Count, const void *Hint = 0) 00207 { 00208 return (pointer)LargeAligned::Acquire((u32)Count * sizeof(T)); 00209 } 00210 00211 void deallocate(pointer Ptr, size_type Count) 00212 { 00213 LargeAligned::Release(Ptr); 00214 } 00215 00216 void construct(pointer Ptr, const T &Val) 00217 { 00218 std::_Construct(Ptr, Val); 00219 } 00220 00221 void destroy(pointer Ptr) 00222 { 00223 std::_Destroy(Ptr); 00224 } 00225 00226 size_type max_size() const 00227 { 00228 return 0x00FFFFFF; 00229 } 00230 00231 template<typename S> 00232 bool operator==(STLLargeAlignedAllocator <S> const &) const throw() 00233 { 00234 return true; 00235 } 00236 00237 template<typename S> 00238 bool operator!=(STLLargeAlignedAllocator <S> const &) const throw() 00239 { 00240 return false; 00241 } 00242 }; 00243 00244 00245 u32 GetCacheLineBytes(); 00246 00247 00248 } // namespace cat 00249 00250 // Provide placement new constructor and delete pair to allow for 00251 // an easy syntax to create objects from the RegionAllocator: 00252 // T *a = new (Aligned()) T(); 00253 // The object can be freed with: 00254 // Aligned::Delete(a); 00255 // Which insures that the destructor is called before freeing memory 00256 CAT_INLINE void *operator new[](std::size_t bytes, cat::Aligned &) throw() 00257 { 00258 return cat::Aligned::Acquire((int)bytes); 00259 } 00260 00261 // Placement "delete": Does not call destructor 00262 CAT_INLINE void operator delete(void *ptr, cat::Aligned &) throw() 00263 { 00264 cat::Aligned::Release(ptr); 00265 } 00266 00267 #endif // CAT_ENDIAN_NEUTRAL_HPP
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.