Shadowrun: Awakened 29 September 2011 - Build 871
RegionAllocator.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_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.

GNU Lesser General Public License 3 Sourceforge.net