Blaze 3.9
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#include <cstdlib>
44#include <new>
49#include <blaze/util/Assert.h>
50#include <blaze/util/EnableIf.h>
52#include <blaze/util/Types.h>
55
56#if BLAZE_WIN32_PLATFORM || BLAZE_WIN64_PLATFORM || BLAZE_MINGW32_PLATFORM || BLAZE_MINGW64_PLATFORM
57# include <malloc.h>
58#endif
59
60
61namespace blaze {
62
63//=================================================================================================
64//
65// BYTE-BASED ALLOCATION FUNCTIONS
66//
67//=================================================================================================
68
69//*************************************************************************************************
82inline byte_t* alignedAllocate( size_t size, size_t alignment )
83{
84 void* raw( nullptr );
85
86#if BLAZE_WIN32_PLATFORM || BLAZE_WIN64_PLATFORM || BLAZE_MINGW64_PLATFORM
87 raw = _aligned_malloc( size, alignment );
88 if( raw == nullptr ) {
89#elif BLAZE_MINGW32_PLATFORM
90 raw = __mingw_aligned_malloc( size, alignment );
91 if( raw == nullptr ) {
92#else
93 alignment = ( alignment < sizeof(void*) ? sizeof(void*) : alignment );
94 if( posix_memalign( &raw, alignment, size ) ) {
95#endif
97 }
98
99 return reinterpret_cast<byte_t*>( raw );
100}
101//*************************************************************************************************
102
103
104//*************************************************************************************************
115inline void alignedDeallocate( const void* address ) noexcept
116{
117#if BLAZE_WIN32_PLATFORM || BLAZE_WIN64_PLATFORM || BLAZE_MINGW64_PLATFORM
118 _aligned_free( const_cast<void*>( address ) );
119#elif BLAZE_MINGW32_PLATFORM
120 __mingw_aligned_free( const_cast<void*>( address ) );
121#else
122 free( const_cast<void*>( address ) );
123#endif
124}
125//*************************************************************************************************
126
127
128
129
130//=================================================================================================
131//
132// TYPE-BASED ALLOCATION FUNCTIONS
133//
134//=================================================================================================
135
136//*************************************************************************************************
156template< typename T
157 , EnableIf_t< IsBuiltin_v<T> >* = nullptr >
158T* allocate( size_t size )
159{
160 constexpr size_t alignment( AlignmentOf_v<T> );
161
162 return reinterpret_cast<T*>( alignedAllocate( size*sizeof(T), alignment ) );
163}
164//*************************************************************************************************
165
166
167//*************************************************************************************************
183template< typename T
184 , DisableIf_t< IsBuiltin_v<T> >* = nullptr >
185T* allocate( size_t size )
186{
187 constexpr size_t alignment ( AlignmentOf_v<T> );
188 constexpr size_t headersize( ( sizeof(size_t) < alignment ) ? ( alignment ) : ( sizeof( size_t ) ) );
189
190 BLAZE_INTERNAL_ASSERT( headersize >= alignment , "Invalid header size detected" );
191 BLAZE_INTERNAL_ASSERT( headersize % alignment == 0UL, "Invalid header size detected" );
192
193 byte_t* const raw( alignedAllocate( size*sizeof(T)+headersize, alignment ) );
194
195 *reinterpret_cast<size_t*>( raw ) = size;
196
197 T* const address( reinterpret_cast<T*>( raw + headersize ) );
198 size_t i( 0UL );
199
200 try {
201 for( ; i<size; ++i ) {
202 blaze::construct_at( address+i );
203 }
204 }
205 catch( ... ) {
206 for( ; i>0UL; --i ) {
207 blaze::destroy_at( address+i );
208 }
209 alignedDeallocate( raw );
210 throw;
211 }
212
213 return address;
214}
215//*************************************************************************************************
216
217
218//*************************************************************************************************
228template< typename T
229 , EnableIf_t< IsBuiltin_v<T> >* = nullptr >
230void deallocate( T* address ) noexcept
231{
232 if( address == nullptr )
233 return;
234
235 alignedDeallocate( address );
236}
237//*************************************************************************************************
238
239
240//*************************************************************************************************
250template< typename T
251 , DisableIf_t< IsBuiltin_v<T> >* = nullptr >
252void deallocate( T* address )
253{
254 if( address == nullptr )
255 return;
256
257 constexpr size_t alignment ( AlignmentOf_v<T> );
258 constexpr 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 const byte_t* const raw = reinterpret_cast<byte_t*>( address ) - headersize;
264 const size_t size( *reinterpret_cast<const size_t*>( raw ) );
265
266 blaze::destroy_n( address, size );
267 alignedDeallocate( raw );
268}
269//*************************************************************************************************
270
271} // namespace blaze
272
273#endif
Header file for the AlignmentOf type trait.
Header file for run time assertion macros.
Header file for the generic construct_at algorithm.
Header file for the generic destroy_at algorithm.
Header file for the generic destroy algorithm.
Header file for the EnableIf class template.
Header file for the IsBuiltin type trait.
Platform-specific system settings.
void construct_at(T *p, Args &&... args)
Constructs the object at the given address.
Definition: ConstructAt.h:58
void destroy_n(ForwardIt first, size_t n)
Destroys the given range of objects .
Definition: Destroy.h:87
void destroy_at(T *p) noexcept
Destroys the object at the given address.
Definition: DestroyAt.h:57
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
void deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
void alignedDeallocate(const void *address) noexcept
Deallocation of aligned memory.
Definition: Memory.h:115
byte_t * alignedAllocate(size_t size, size_t alignment)
Aligned array allocation.
Definition: Memory.h:82
unsigned char byte_t
Byte data type of the Blaze library.
Definition: Types.h:79
T * allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:158
#define BLAZE_THROW_BAD_ALLOC
Macro for the emission of a std::bad_alloc exception.
Definition: Exception.h:139
Header file for exception macros.
Header file for basic type definitions.