00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifdef _MSC_VER
00031 # pragma once
00032 # pragma warning( push )
00033 # pragma warning( disable : 4311 4786 )
00034 # pragma comment (lib, "exmat.lib")
00035 #endif // _MSC_VER
00036
00037 #ifndef _EXMAT_ALLOCATOR_H
00038 #define _EXMAT_ALLOCATOR_H
00039
00040 #include "Config.h"
00041 #include <malloc.h>
00042 #include <new>
00043 #include <exception>
00044
00045
00046
00047 #if defined(free)
00048 # define EXMAT_MCBK_FREE free
00049 # undef free
00050 #endif
00051
00052
00053 namespace exmat {
00054
00055
00057 static EXMAT_INLINE1
00058 void* AlignedMalloc(size_t size, size_t align) {
00059
00060
00061 void* mem = malloc(size+align);
00062
00063 void* newmem = reinterpret_cast<void*>((reinterpret_cast<int>(mem) + align) & ~(align-1));
00064
00065 *(reinterpret_cast<int*>(reinterpret_cast<int>(newmem)-sizeof(void*))) = int(mem);
00066
00067 return newmem;
00068 }
00069
00071 static EXMAT_INLINE2
00072 void AlignedFree(void* p) {
00073 void* mem = *(reinterpret_cast<void**>(int(p)-sizeof(void*)));
00074 free(mem);
00075 }
00076
00077
00079 template<int StackSize, int align_bytes>
00080 class AlignedStack
00081 {
00082 public:
00084 enum {
00085
00086 MaxAllocation = StackSize / align_bytes
00087 };
00088
00089 AlignedStack()
00090 : nUsedByte(0), nAlocation(0),
00091 pRawPtr( reinterpret_cast<char* const>(malloc(StackSize + align_bytes)) ),
00092 pMemory( reinterpret_cast<char*>((((intptr_t)pRawPtr + align_bytes - 1) / align_bytes) * align_bytes) )
00093 {
00094 }
00095
00096 ~AlignedStack() {
00097 ::free(pRawPtr);
00098 }
00099
00101 void* allocate(size_t size) {
00102 int alignedSize = int((size + align_bytes - 1) / align_bytes) * align_bytes;
00103
00104 if(nUsedByte + alignedSize > StackSize)
00105 throw std::bad_alloc();
00106 AlloHistory[nAlocation++] = alignedSize;
00107 nUsedByte += alignedSize;
00108 char* pRet = pMemory;
00109 pMemory += alignedSize;
00110 return pRet;
00111 }
00112
00114 void free() {
00115 int size = (int)AlloHistory[nAlocation--];
00116 nUsedByte -= size;
00117 pMemory -= size;
00118 }
00119
00120 private:
00121
00122 AlignedStack(const AlignedStack&);
00123 AlignedStack& operator=(const AlignedStack&);
00124 private:
00126 size_t nUsedByte;
00128 size_t nAlocation;
00129 char* const pRawPtr;
00130 char* pMemory;
00132 size_t AlloHistory[MaxAllocation];
00133 };
00134
00135 namespace PNS {
00136 AlignedStack<SIMD_ALIGNED_STACK_SIZE, SIMD_ALIGN_BYTE>&
00137 get_aligned_stack();
00138
00139
00140
00141
00142 };
00143
00145 static EXMAT_INLINE2 void* aligned_stack_allocate(size_t size) {
00146 return exmat::PNS::get_aligned_stack().allocate(size);
00147 }
00148
00150 static EXMAT_INLINE2 void aligned_stack_free() {
00151 exmat::PNS::get_aligned_stack().free();
00152 }
00153
00154 }
00155
00156
00157
00158 #if defined(EXMAT_MCBK_FREE)
00159 # define free EXMAT_MCBK_FREE
00160 # undef EXMAT_MCBK_FREE
00161 #endif
00162
00163
00164 #ifdef _MSC_VER
00165 # pragma warning( pop )
00166 #endif // _MSC_VER
00167
00168 #endif // _EXMAT_ALLOCATOR_H