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/DisableIf.h>
50 #include <blaze/util/EnableIf.h>
51 #include <blaze/util/Exception.h>
52 #include <blaze/util/Types.h>
55 
56 
57 namespace blaze {
58 
59 //=================================================================================================
60 //
61 // BACKEND ALLOCATION FUNCTIONS
62 //
63 //=================================================================================================
64 
65 //*************************************************************************************************
79 inline byte_t* allocate_backend( size_t size, size_t alignment )
80 {
81  void* raw( nullptr );
82 
83 #if defined(_MSC_VER)
84  raw = _aligned_malloc( size, alignment );
85  if( raw == nullptr ) {
86 #else
87  if( posix_memalign( &raw, alignment, size ) ) {
88 #endif
90  }
91 
92  return reinterpret_cast<byte_t*>( raw );
93 }
95 //*************************************************************************************************
96 
97 
98 //*************************************************************************************************
109 inline void deallocate_backend( const void* address ) noexcept
110 {
111 #if defined(_MSC_VER)
112  _aligned_free( const_cast<void*>( address ) );
113 #else
114  free( const_cast<void*>( address ) );
115 #endif
116 }
118 //*************************************************************************************************
119 
120 
121 
122 
123 //=================================================================================================
124 //
125 // ALLOCATION FUNCTIONS
126 //
127 //=================================================================================================
128 
129 //*************************************************************************************************
149 template< typename T >
150 EnableIf_< IsBuiltin<T>, T* > allocate( size_t size )
151 {
152  const size_t alignment( AlignmentOf<T>::value );
153 
154  if( alignment >= 8UL ) {
155  return reinterpret_cast<T*>( allocate_backend( size*sizeof(T), alignment ) );
156  }
157  else return ::new T[size];
158 }
159 //*************************************************************************************************
160 
161 
162 //*************************************************************************************************
178 template< typename T >
179 DisableIf_< IsBuiltin<T>, T* > allocate( size_t size )
180 {
181  const size_t alignment ( AlignmentOf<T>::value );
182  const size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
183 
184  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
185  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
186 
187  if( alignment >= 8UL )
188  {
189  byte_t* const raw( allocate_backend( size*sizeof(T)+headersize, alignment ) );
190 
191  *reinterpret_cast<size_t*>( raw ) = size;
192 
193  T* const address( reinterpret_cast<T*>( raw + headersize ) );
194  size_t i( 0UL );
195 
196  try {
197  for( ; i<size; ++i )
198  ::new (address+i) T();
199  }
200  catch( ... ) {
201  while( i != 0UL )
202  address[--i].~T();
203  deallocate_backend( raw );
204  throw;
205  }
206 
207  return address;
208  }
209  else return ::new T[size];
210 }
211 //*************************************************************************************************
212 
213 
214 //*************************************************************************************************
224 template< typename T >
225 EnableIf_< IsBuiltin<T> > deallocate( T* address ) noexcept
226 {
227  if( address == nullptr )
228  return;
229 
230  const size_t alignment( AlignmentOf<T>::value );
231 
232  if( alignment >= 8UL ) {
233  deallocate_backend( address );
234  }
235  else delete[] address;
236 }
237 //*************************************************************************************************
238 
239 
240 //*************************************************************************************************
250 template< typename T >
252 {
253  if( address == nullptr )
254  return;
255 
256  const size_t alignment ( AlignmentOf<T>::value );
257  const size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
258 
259  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
260  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
261 
262  if( alignment >= 8UL )
263  {
264  const byte_t* const raw = reinterpret_cast<byte_t*>( address ) - headersize;
265 
266  const size_t size( *reinterpret_cast<const size_t*>( raw ) );
267  for( size_t i=0UL; i<size; ++i )
268  address[i].~T();
269 
270  deallocate_backend( raw );
271  }
272  else delete[] address;
273 }
274 //*************************************************************************************************
275 
276 } // namespace blaze
277 
278 #endif
Header file for the AlignmentOf type trait.
Header file for basic type definitions.
unsigned char byte_t
Byte data type of the Blaze library.The byte data type is guaranteed to be an integral data type of s...
Definition: Types.h:79
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
Header file for exception macros.
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
#define BLAZE_THROW_BAD_ALLOC
Macro for the emission of a std::bad_alloc exception.This macro encapsulates the default way of Blaze...
Definition: Exception.h:139
EnableIf_< IsBuiltin< T >, T * > allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:150
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the EnableIf class template.
Header file for run time assertion macros.
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
Header file for the IsBuiltin type trait.
#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:207