phdMesh  Version of the Day
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups
FixedPoolAlloc.hpp
1 /*------------------------------------------------------------------------*/
2 /* phdMesh : Parallel Heterogneous Dynamic unstructured Mesh */
3 /* Copyright (2007) Sandia Corporation */
4 /* */
5 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
6 /* license for use of this work by or on behalf of the U.S. Government. */
7 /* */
8 /* This library is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU Lesser General Public License as */
10 /* published by the Free Software Foundation; either version 2.1 of the */
11 /* License, or (at your option) any later version. */
12 /* */
13 /* This library is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* Lesser General Public License for more details. */
17 /* */
18 /* You should have received a copy of the GNU Lesser General Public */
19 /* License along with this library; if not, write to the Free Software */
20 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 */
21 /* USA */
22 /*------------------------------------------------------------------------*/
28 #ifndef util_FixedPoolAlloc_hpp
29 #define util_FixedPoolAlloc_hpp
30 
31 #include <cstddef>
32 
33 namespace phdmesh {
34 
35 void ** fixed_pool_buffer_init( const std::size_t nbyte_total ,
36  const std::size_t nbyte ,
37  void ** );
38 
39 void throw_fixed_pool_buffer_bad_size( const std::size_t nbyte_total ,
40  const std::size_t nbyte_first ,
41  const std::size_t nbyte );
42 
43 void throw_fixed_pool_buffer_exhausted( const std::size_t nbyte_total ,
44  const std::size_t nbyte );
45 
46 void throw_fixed_pool_buffer_bad_deallocate( const std::size_t ,
47  void * const );
48 
49 template<unsigned NBYTE>
50 class FixedPoolBuffer {
51 private:
52 
53  enum { NWORD = NBYTE / sizeof(void*) };
54 
55  std::size_t size ;
56  void ** link ;
57  void * mem[ NWORD ];
58 
59  FixedPoolBuffer( const FixedPoolBuffer<NBYTE> & );
60  FixedPoolBuffer<NBYTE> & operator = ( const FixedPoolBuffer<NBYTE> & );
61 
62 public:
63 
64  ~FixedPoolBuffer() {}
65 
66  FixedPoolBuffer() : size(0) { link = mem ; }
67 
68  bool full() const { return ! link ; }
69 
70  void * allocate( std::size_t nbyte )
71  {
72  void * p = NULL ;
73  if ( nbyte ) {
74  if ( ! size ) { // Initialize on the first call
75  size = nbyte ;
76  fixed_pool_buffer_init(NBYTE,size,link);
77  }
78  else if ( nbyte != size ) {
79  throw_fixed_pool_buffer_bad_size(NBYTE,size,nbyte);
80  }
81  if ( ! link ) {
82  throw_fixed_pool_buffer_exhausted(NBYTE,nbyte);
83  }
84  p = link ;
85  link = reinterpret_cast<void**>( *link );
86  }
87  return p ;
88  }
89 
90  void deallocate( void * p , std::size_t nbyte )
91  {
92  if ( nbyte != size ) {
93  throw_fixed_pool_buffer_bad_size(NBYTE,size,nbyte);
94  }
95  void ** const vp = reinterpret_cast<void**>(p);
96  if ( vp < mem || ( mem + NWORD - size ) < vp ) {
97  throw_fixed_pool_buffer_bad_deallocate(NBYTE,p);
98  }
99  *vp = link ;
100  link = reinterpret_cast<void**>(vp);
101  return ;
102  }
103 };
104 
105 
106 template<unsigned NBYTE,typename T=void*>
107 class FixedPoolAllocator {
108 private:
109 
110  FixedPoolBuffer<NBYTE> * buffer ;
111 
112  FixedPoolAllocator<NBYTE,T> &
113  operator = ( const FixedPoolAllocator<NBYTE,T> & );
114 
115  template<unsigned M,typename U> friend class FixedPoolAllocator ;
116 
117 public:
118 
119  typedef FixedPoolBuffer<NBYTE> buffer_type ;
120 
121  typedef T value_type;
122  typedef std::size_t size_type;
123  typedef T* pointer;
124  typedef const T* const_pointer;
125  typedef T& reference;
126  typedef const T& const_reference;
127  typedef std::ptrdiff_t difference_type;
128 
129  pointer address( reference value ) const { return & value ; }
130  const_pointer address( const_reference value ) const { return & value ; }
131 
132  ~FixedPoolAllocator() {}
133 
134  FixedPoolAllocator() : buffer(NULL) {}
135 
136  FixedPoolAllocator( const FixedPoolAllocator<NBYTE,T> & a )
137  : buffer(a.buffer) {}
138 
139  explicit FixedPoolAllocator( buffer_type & b ) : buffer( & b ) {}
140 
141  template<typename U>
142  struct rebind { typedef FixedPoolAllocator<NBYTE,U> other ; };
143 
144  template<typename U>
145  FixedPoolAllocator( const FixedPoolAllocator<NBYTE,U> & a )
146  : buffer(a.buffer) {}
147 
148  pointer allocate( size_type n , const void * = NULL )
149  { return reinterpret_cast<pointer>( buffer->allocate( n * sizeof(T) ) ); }
150 
151  void deallocate( pointer p , size_type n )
152  { buffer->deallocate(p, n * sizeof(T) ); }
153 
154  void construct( pointer p , const T & val ) { new(p) T(val); }
155  void destroy( pointer p ) { p->~T(); }
156 
157  template<typename U>
158  void construct( U * p , const U & val ) { new(p) U(val); }
159 
160  template<typename U>
161  void destroy( U * p ) { p->~U(); }
162 
163  size_type max_size() const { return NBYTE / sizeof(T) ; }
164 };
165 
166 template<unsigned NBYTE,typename T>
167 bool operator == ( const FixedPoolAllocator<NBYTE,T> & lhs ,
168  const FixedPoolAllocator<NBYTE,T> & rhs )
169 { return lhs.buffer == rhs.buffer ; }
170 
171 template<unsigned NBYTE,typename T>
172 bool operator != ( const FixedPoolAllocator<NBYTE,T> & lhs ,
173  const FixedPoolAllocator<NBYTE,T> & rhs )
174 { return lhs.buffer != rhs.buffer ; }
175 
176 }
177 
178 #endif
179