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 <blaze/util/Assert.h>
49 #include <blaze/util/Byte.h>
50 #include <blaze/util/DisableIf.h>
51 #include <blaze/util/EnableIf.h>
52 #include <blaze/util/Exception.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
92  }
93 
94  return reinterpret_cast<byte*>( raw );
95 }
97 //*************************************************************************************************
98 
99 
100 //*************************************************************************************************
111 inline void deallocate_backend( const void* address )
112 {
113 #if defined(_MSC_VER)
114  _aligned_free( const_cast<void*>( address ) );
115 #else
116  free( const_cast<void*>( address ) );
117 #endif
118 }
120 //*************************************************************************************************
121 
122 
123 
124 
125 //=================================================================================================
126 //
127 // ALLOCATION FUNCTIONS
128 //
129 //=================================================================================================
130 
131 //*************************************************************************************************
151 template< typename T >
152 typename EnableIf< IsBuiltin<T>, T* >::Type allocate( size_t size )
153 {
154  const size_t alignment( AlignmentOf<T>::value );
155 
156  if( alignment >= 8UL ) {
157  return reinterpret_cast<T*>( allocate_backend( size*sizeof(T), alignment ) );
158  }
159  else return ::new T[size];
160 }
161 //*************************************************************************************************
162 
163 
164 //*************************************************************************************************
180 template< typename T >
181 typename DisableIf< IsBuiltin<T>, T* >::Type allocate( size_t size )
182 {
183  const size_t alignment ( AlignmentOf<T>::value );
184  const size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
185 
186  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
187  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
188 
189  if( alignment >= 8UL )
190  {
191  byte* const raw( allocate_backend( size*sizeof(T)+headersize, alignment ) );
192 
193  *reinterpret_cast<size_t*>( raw ) = size;
194 
195  T* const address( reinterpret_cast<T*>( raw + headersize ) );
196  size_t i( 0UL );
197 
198  try {
199  for( ; i<size; ++i )
200  ::new (address+i) T();
201  }
202  catch( ... ) {
203  while( i != 0UL )
204  address[--i].~T();
205  deallocate_backend( raw );
206  throw;
207  }
208 
209  return address;
210  }
211  else return ::new T[size];
212 }
213 //*************************************************************************************************
214 
215 
216 //*************************************************************************************************
226 template< typename T >
227 typename EnableIf< IsBuiltin<T> >::Type deallocate( T* address )
228 {
229  if( address == NULL )
230  return;
231 
232  const size_t alignment( AlignmentOf<T>::value );
233 
234  if( alignment >= 8UL ) {
235  deallocate_backend( address );
236  }
237  else delete[] address;
238 }
239 //*************************************************************************************************
240 
241 
242 //*************************************************************************************************
252 template< typename T >
253 typename DisableIf< IsBuiltin<T> >::Type deallocate( T* address )
254 {
255  if( address == NULL )
256  return;
257 
258  const size_t alignment ( AlignmentOf<T>::value );
259  const size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
260 
261  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
262  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
263 
264  if( alignment >= 8UL )
265  {
266  const byte* const raw = reinterpret_cast<byte*>( address ) - headersize;
267 
268  const size_t size( *reinterpret_cast<const size_t*>( raw ) );
269  for( size_t i=0UL; i<size; ++i )
270  address[i].~T();
271 
272  deallocate_backend( raw );
273  }
274  else delete[] address;
275 }
276 //*************************************************************************************************
277 
278 } // namespace blaze
279 
280 #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:252
#define BLAZE_THROW_BAD_ALLOC
Macro for the emission of a std::bad_alloc exceptionThis macro encapsulates the default way of Blaze ...
Definition: Exception.h:139
EnableIf< IsBuiltin< T >, T * >::Type allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:152
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:227
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
Header file for exception macros.
#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.