Shadowrun: Awakened 29 September 2011 - Build 871
AlignedAlloc.hpp
Go to the documentation of this file.
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.

GNU Lesser General Public License 3 Sourceforge.net