phdMesh Version of the Day
FixedPoolAlloc.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*      phdMesh : Parallel Heterogneous Dynamic unstructured Mesh         */
00003 /*                Copyright (2007) Sandia Corporation                     */
00004 /*                                                                        */
00005 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00006 /*  license for use of this work by or on behalf of the U.S. Government.  */
00007 /*                                                                        */
00008 /*  This library is free software; you can redistribute it and/or modify  */
00009 /*  it under the terms of the GNU Lesser General Public License as        */
00010 /*  published by the Free Software Foundation; either version 2.1 of the  */
00011 /*  License, or (at your option) any later version.                       */
00012 /*                                                                        */
00013 /*  This library is distributed in the hope that it will be useful,       */
00014 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
00015 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     */
00016 /*  Lesser General Public License for more details.                       */
00017 /*                                                                        */
00018 /*  You should have received a copy of the GNU Lesser General Public      */
00019 /*  License along with this library; if not, write to the Free Software   */
00020 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   */
00021 /*  USA                                                                   */
00022 /*------------------------------------------------------------------------*/
00028 #ifndef util_FixedPoolAlloc_hpp
00029 #define util_FixedPoolAlloc_hpp
00030 
00031 #include <cstddef>
00032 
00033 namespace phdmesh {
00034 
00035 void ** fixed_pool_buffer_init( const std::size_t nbyte_total ,
00036                                 const std::size_t nbyte ,
00037                                 void ** );
00038 
00039 void throw_fixed_pool_buffer_bad_size( const std::size_t nbyte_total ,
00040                                        const std::size_t nbyte_first ,
00041                                        const std::size_t nbyte );
00042 
00043 void throw_fixed_pool_buffer_exhausted( const std::size_t nbyte_total ,
00044                                         const std::size_t nbyte );
00045 
00046 void throw_fixed_pool_buffer_bad_deallocate( const std::size_t ,
00047                                              void * const );
00048 
00049 template<unsigned NBYTE>
00050 class FixedPoolBuffer {
00051 private:
00052 
00053   enum { NWORD = NBYTE / sizeof(void*) };
00054 
00055   std::size_t size ;
00056   void     ** link ;
00057   void      * mem[ NWORD ];
00058 
00059   FixedPoolBuffer( const FixedPoolBuffer<NBYTE> & );
00060   FixedPoolBuffer<NBYTE> & operator = ( const FixedPoolBuffer<NBYTE> & );
00061 
00062 public:
00063 
00064   ~FixedPoolBuffer() {}
00065 
00066   FixedPoolBuffer() : size(0) { link = mem ; }
00067 
00068   bool full() const { return ! link ; }
00069 
00070   void * allocate( std::size_t nbyte )
00071     {
00072       void * p = NULL ;
00073       if ( nbyte ) {
00074         if ( ! size ) { // Initialize on the first call
00075           size = nbyte ;
00076           fixed_pool_buffer_init(NBYTE,size,link);
00077         }
00078         else if ( nbyte != size ) {
00079           throw_fixed_pool_buffer_bad_size(NBYTE,size,nbyte);
00080         }
00081         if ( ! link ) {
00082           throw_fixed_pool_buffer_exhausted(NBYTE,nbyte);
00083         }
00084         p = link ;
00085         link = reinterpret_cast<void**>( *link );
00086       }
00087       return p ;
00088     }
00089 
00090   void deallocate( void * p , std::size_t nbyte )
00091     {
00092       if ( nbyte != size ) {
00093         throw_fixed_pool_buffer_bad_size(NBYTE,size,nbyte);
00094       }
00095       void ** const vp = reinterpret_cast<void**>(p);
00096       if ( vp < mem || ( mem + NWORD - size ) < vp ) {
00097         throw_fixed_pool_buffer_bad_deallocate(NBYTE,p);
00098       }
00099       *vp = link ;
00100       link = reinterpret_cast<void**>(vp);
00101       return ;
00102     }
00103 };
00104 
00105 
00106 template<unsigned NBYTE,typename T=void*>
00107 class FixedPoolAllocator {
00108 private:
00109 
00110   FixedPoolBuffer<NBYTE> * buffer ;
00111 
00112   FixedPoolAllocator<NBYTE,T> &
00113     operator = ( const FixedPoolAllocator<NBYTE,T> & );
00114 
00115   template<unsigned M,typename U> friend class FixedPoolAllocator ;
00116  
00117 public:
00118 
00119   typedef FixedPoolBuffer<NBYTE> buffer_type ;
00120 
00121   typedef           T value_type;
00122   typedef std::size_t size_type;
00123   typedef          T* pointer;
00124   typedef    const T* const_pointer;
00125   typedef          T& reference;
00126   typedef    const T& const_reference;
00127   typedef std::ptrdiff_t difference_type;
00128 
00129   pointer       address( reference       value ) const { return & value ; }
00130   const_pointer address( const_reference value ) const { return & value ; }
00131 
00132   ~FixedPoolAllocator() {}
00133 
00134   FixedPoolAllocator() : buffer(NULL) {}
00135 
00136   FixedPoolAllocator( const FixedPoolAllocator<NBYTE,T> & a )
00137     : buffer(a.buffer) {}
00138 
00139   explicit FixedPoolAllocator( buffer_type & b ) : buffer( & b ) {}
00140 
00141   template<typename U>
00142   struct rebind { typedef FixedPoolAllocator<NBYTE,U> other ; };
00143 
00144   template<typename U>
00145   FixedPoolAllocator( const FixedPoolAllocator<NBYTE,U> & a )
00146     : buffer(a.buffer) {}
00147 
00148   pointer allocate( size_type n , const void * = NULL )
00149     { return reinterpret_cast<pointer>( buffer->allocate( n * sizeof(T) ) ); }
00150 
00151   void deallocate( pointer p , size_type n )
00152     { buffer->deallocate(p, n * sizeof(T) ); }
00153 
00154   void construct( pointer p , const T & val ) { new(p) T(val); }
00155   void destroy(   pointer p ) { p->~T(); }
00156 
00157   template<typename U>
00158   void construct( U * p , const U & val ) { new(p) U(val); }
00159 
00160   template<typename U>
00161   void destroy( U * p ) { p->~U(); }
00162 
00163   size_type max_size() const { return NBYTE / sizeof(T) ; }
00164 };
00165 
00166 template<unsigned NBYTE,typename T>
00167 bool operator == ( const FixedPoolAllocator<NBYTE,T> & lhs ,
00168                    const FixedPoolAllocator<NBYTE,T> & rhs )
00169 { return lhs.buffer == rhs.buffer ; }
00170 
00171 template<unsigned NBYTE,typename T>
00172 bool operator != ( const FixedPoolAllocator<NBYTE,T> & lhs ,
00173                    const FixedPoolAllocator<NBYTE,T> & rhs )
00174 { return lhs.buffer != rhs.buffer ; }
00175 
00176 }
00177 
00178 #endif
00179 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator