| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*
- Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of LibCat nor the names of its contributors may be used
- to endorse or promote products derived from this software without
- specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
- */
- #ifndef CAT_REGION_ALLOCATOR_HPP
- #define CAT_REGION_ALLOCATOR_HPP
- #include <cat/Singleton.hpp>
- #include <memory>
- #include <xstring>
- #include <sstream>
- namespace cat {
- // A region-based allocator that is lock-free, supporting
- // a range of allocation block sizes that are pre-allocated
- // in a pre-determined way, tuned to the application.
- class RegionAllocator : public Singleton<RegionAllocator>
- {
- CAT_SINGLETON(RegionAllocator);
- protected:
- struct RegionInfoHead
- {
- u32 next_bitmap_entry;
- };
- struct RegionInfo : public RegionInfoHead
- {
- volatile u32 bitmap[1];
- };
- // 64, 128, 256, 512, 1024, 2048 only
- static const u32 REGION_COUNT = 6;
- static const u32 BLOCK_SIZE[REGION_COUNT];
- u32 bytes_overall;
- u32 blocks_per_region[REGION_COUNT];
- u32 bitmap_dwords[REGION_COUNT];
- u8 *regions[REGION_COUNT];
- RegionInfo *region_info[REGION_COUNT];
- //u32 errors;
- public:
- bool Valid();
- void Shutdown();
- public:
- void *Acquire(u32 bytes);
- void *Resize(void *ptr, u32 bytes);
- void Release(void *ptr);
- template<class T>
- CAT_INLINE void Delete(T *ptr)
- {
- ptr->~T();
- Release(ptr);
- }
- // Acquires a buffer from the allocator that is the size of the type.
- // It further allocates a number of extra bytes beyond the end of the buffer.
- // Release the buffer with:
- // RegionAllocator::ii->Release(ptr);
- template<class T> T *AcquireBuffer(u32 extra_bytes = 0)
- {
- return reinterpret_cast<T*>( Acquire(sizeof(T) + extra_bytes) );
- }
- };
- // Use STLRegionAllocator in place of the standard STL allocator
- // to make use of the RegionAllocator in STL types. Some common
- // usage typedefs follow this class definition below.
- template<typename T>
- class STLRegionAllocator
- {
- public:
- typedef size_t size_type;
- typedef size_t difference_type;
- typedef T *pointer;
- typedef const T *const_pointer;
- typedef T &reference;
- typedef const T &const_reference;
- typedef T value_type;
- template<typename S>
- struct rebind
- {
- typedef STLRegionAllocator<S> other;
- };
- pointer address(reference X) const
- {
- return &X;
- }
- const_pointer address(const_reference X) const
- {
- return &X;
- }
- STLRegionAllocator() throw ()
- {
- }
- template<typename S>
- STLRegionAllocator(const STLRegionAllocator<S> &cp) throw ()
- {
- }
- template<typename S>
- STLRegionAllocator<T> &operator=(const STLRegionAllocator<S> &cp) throw ()
- {
- return *this;
- }
- pointer allocate(size_type Count, const void *Hint = 0)
- {
- return (pointer)RegionAllocator::ii->Acquire((u32)Count * sizeof(T));
- }
- void deallocate(pointer Ptr, size_type Count)
- {
- RegionAllocator::ii->Release(Ptr);
- }
- void construct(pointer Ptr, const T &Val)
- {
- std::_Construct(Ptr, Val);
- }
- void destroy(pointer Ptr)
- {
- std::_Destroy(Ptr);
- }
- size_type max_size() const
- {
- return 0x00FFFFFF;
- }
- template<typename S>
- bool operator==(STLRegionAllocator <S> const &) const throw()
- {
- return true;
- }
- template<typename S>
- bool operator!=(STLRegionAllocator <S> const &) const throw()
- {
- return false;
- }
- };
- // Common usage typedefs for using RegionAllocator as the STL allocator
- typedef std::basic_ostringstream<char, std::char_traits<char>, STLRegionAllocator<char> > region_ostringstream;
- typedef std::basic_string<char, std::char_traits<char>, STLRegionAllocator<char> > region_string;
- } // namespace cat
- // Provide placement new constructor and delete pair to allow for
- // an easy syntax to create objects from the RegionAllocator:
- // T *a = new (RegionAllocator::ii) T();
- // The object can be freed with:
- // RegionAllocator::ii->Delete(a);
- // Which insures that the destructor is called before freeing memory
- inline void *operator new(size_t bytes, cat::RegionAllocator *allocator)
- {
- return allocator->Acquire((cat::u32)bytes);
- }
- inline void operator delete(void *ptr, cat::RegionAllocator *allocator)
- {
- allocator->Release(ptr);
- }
- #endif // CAT_REGION_ALLOCATOR_HPP
|