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 BLAZE_WIN64_PLATFORM || BLAZE_MINGW64_PLATFORM || BLAZE_MINGW32_PLATFORM
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 BLAZE_WIN64_PLATFORM || BLAZE_MINGW64_PLATFORM
84  raw = _aligned_malloc( size, alignment );
85  if( raw == nullptr ) {
86 #elif BLAZE_MINGW32_PLATFORM
87  raw = __mingw_aligned_malloc( size, alignment );
88  if( raw == nullptr ) {
89 #else
90  alignment = ( alignment < sizeof(void*) ? sizeof(void*) : alignment );
91  if( posix_memalign( &raw, alignment, size ) ) {
92 #endif
94  }
95 
96  return reinterpret_cast<byte_t*>( raw );
97 }
99 //*************************************************************************************************
100 
101 
102 //*************************************************************************************************
113 inline void deallocate_backend( const void* address ) noexcept
114 {
115 #if BLAZE_WIN64_PLATFORM || BLAZE_MINGW64_PLATFORM
116  _aligned_free( const_cast<void*>( address ) );
117 #elif BLAZE_MINGW32_PLATFORM
118  __mingw_aligned_free( const_cast<void*>( address ) );
119 #else
120  free( const_cast<void*>( address ) );
121 #endif
122 }
124 //*************************************************************************************************
125 
126 
127 
128 
129 //=================================================================================================
130 //
131 // ALLOCATION FUNCTIONS
132 //
133 //=================================================================================================
134 
135 //*************************************************************************************************
155 template< typename T >
157 {
158  constexpr size_t alignment( AlignmentOf_v<T> );
159 
160  return reinterpret_cast<T*>( allocate_backend( size*sizeof(T), alignment ) );
161 }
162 //*************************************************************************************************
163 
164 
165 //*************************************************************************************************
181 template< typename T >
183 {
184  constexpr size_t alignment ( AlignmentOf_v<T> );
185  constexpr size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
186 
187  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
188  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
189 
190  byte_t* 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 //*************************************************************************************************
211 
212 
213 //*************************************************************************************************
223 template< typename T >
224 EnableIf_t< IsBuiltin_v<T> > deallocate( T* address ) noexcept
225 {
226  if( address == nullptr )
227  return;
228 
229  deallocate_backend( address );
230 }
231 //*************************************************************************************************
232 
233 
234 //*************************************************************************************************
244 template< typename T >
246 {
247  if( address == nullptr )
248  return;
249 
250  constexpr size_t alignment ( AlignmentOf_v<T> );
251  constexpr size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
252 
253  BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
254  BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
255 
256  const byte_t* const raw = reinterpret_cast<byte_t*>( address ) - headersize;
257 
258  const size_t size( *reinterpret_cast<const size_t*>( raw ) );
259  for( size_t i=0UL; i<size; ++i )
260  address[i].~T();
261 
262  deallocate_backend( raw );
263 }
264 //*************************************************************************************************
265 
266 } // namespace blaze
267 
268 #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
Header file for exception macros.
#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
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the EnableIf class template.
Header file for run time assertion macros.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
EnableIf_t< IsBuiltin_v< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:224
Header file for the IsBuiltin type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
EnableIf_t< IsBuiltin_v< T >, T *> allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:156
#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