Memory.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_UTIL_MEMORY_H_
36 #define _BLAZE_UTIL_MEMORY_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #if defined(_MSC_VER)
44 # include <malloc.h>
45 #endif
46 #include <cstdlib>
47 #include <new>
48 #include <stdexcept>
49 #include <blaze/util/Assert.h>
50 #include <blaze/util/Byte.h>
51 #include <blaze/util/DisableIf.h>
52 #include <blaze/util/EnableIf.h>
53 #include <blaze/util/Null.h>
54 #include <blaze/util/Types.h>
57 
58 
59 namespace blaze {
60 
61 //=================================================================================================
62 //
63 // BACKEND ALLOCATION FUNCTIONS
64 //
65 //=================================================================================================
66 
67 //*************************************************************************************************
81 inline byte* allocate_backend( size_t size, size_t alignment )
82 {
83  void* raw( NULL );
84 
85 #if defined(_MSC_VER)
86  raw = _aligned_malloc( size, alignment );
87  if( raw == NULL )
88 #else
89  if( posix_memalign( &raw, alignment, size ) )
90 #endif
91  throw std::bad_alloc();
92 
93  return reinterpret_cast<byte*>( raw );
94 }
96 //*************************************************************************************************
97 
98 
99 //*************************************************************************************************
110 inline void deallocate_backend( const void* address )
111 {
112 #if defined(_MSC_VER)
113  _aligned_free( const_cast<void*>( address ) );
114 #else
115  free( const_cast<void*>( address ) );
116 #endif
117 }
119 //*************************************************************************************************
120 
121 
122 
123 
124 //=================================================================================================
125 //
126 // ALLOCATION FUNCTIONS
127 //
128 //=================================================================================================
129 
130 //*************************************************************************************************
150 template< typename T >
151 typename EnableIf< IsBuiltin<T>, T* >::Type allocate( size_t size )
152 {
153  const size_t alignment( AlignmentOf<T>::value );
154 
155  if( alignment >= 8UL ) {
156  return reinterpret_cast<T*>( allocate_backend( size*sizeof(T), alignment ) );
157  }
158  else return ::new T[size];
159 }
160 //*************************************************************************************************
161 
162 
163 //*************************************************************************************************
179 template< typename T >
180 typename DisableIf< IsBuiltin<T>, T* >::Type allocate( size_t size )
181 {
182  const size_t alignment ( AlignmentOf<T>::value );
183  const size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
184 
185  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
186  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
187 
188  if( alignment >= 8UL )
189  {
190  byte* const raw( allocate_backend( size*sizeof(T)+headersize, alignment ) );
191 
192  *reinterpret_cast<size_t*>( raw ) = size;
193 
194  T* const address( reinterpret_cast<T*>( raw + headersize ) );
195  size_t i( 0UL );
196 
197  try {
198  for( ; i<size; ++i )
199  ::new (address+i) T();
200  }
201  catch( ... ) {
202  while( i != 0UL )
203  address[--i].~T();
204  deallocate_backend( raw );
205  throw;
206  }
207 
208  return address;
209  }
210  else return ::new T[size];
211 }
212 //*************************************************************************************************
213 
214 
215 //*************************************************************************************************
225 template< typename T >
226 typename EnableIf< IsBuiltin<T> >::Type deallocate( T* address )
227 {
228  if( address == NULL )
229  return;
230 
231  const size_t alignment( AlignmentOf<T>::value );
232 
233  if( alignment >= 8UL ) {
234  deallocate_backend( address );
235  }
236  else delete[] address;
237 }
238 //*************************************************************************************************
239 
240 
241 //*************************************************************************************************
251 template< typename T >
252 typename DisableIf< IsBuiltin<T> >::Type deallocate( T* address )
253 {
254  if( address == NULL )
255  return;
256 
257  const size_t alignment ( AlignmentOf<T>::value );
258  const size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
259 
260  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
261  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
262 
263  if( alignment >= 8UL )
264  {
265  const byte* const raw = reinterpret_cast<byte*>( address ) - headersize;
266 
267  const size_t size( *reinterpret_cast<const size_t*>( raw ) );
268  for( size_t i=0UL; i<size; ++i )
269  address[i].~T();
270 
271  deallocate_backend( raw );
272  }
273  else delete[] address;
274 }
275 //*************************************************************************************************
276 
277 } // namespace blaze
278 
279 #endif
Header file for the AlignmentOf type trait.
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
EnableIf< IsBuiltin< T >, T * >::Type allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:151
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
EnableIf< IsBuiltin< T > >::Type deallocate(T *address)
Deallocation of memory for built-in data types.
Definition: Memory.h:226
Header file for the EnableIf class template.
Header file for the byte type.
Header file for run time assertion macros.
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Header file for the IsBuiltin type trait.
unsigned char byte
Byte data type of the Blaze library.The byte data type is guaranteed to be an integral data type of s...
Definition: Byte.h:61
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Evaluation of the required alignment of the given data type.The AlignmentOf type trait template evalu...
Definition: AlignmentOf.h:77
Header file for a safe C++ NULL pointer implementation.