Allocator.h

Go to the documentation of this file.
00001 /*
00002  * Expression Template Matrix Library
00003  *
00004  * Copyright (C) 2004 - 2006 Ricky Lung <mtlung@users.sourceforge.net>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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")    /* link with exmat library */
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 // Backup the potential macro "free"
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     // Assert align is power of 2, and bigger than sizeof(int)
00060     // Assert int have the same size of (void*)
00061     void* mem = malloc(size+align);
00062     // Calculate the aligned value
00063     void* newmem = reinterpret_cast<void*>((reinterpret_cast<int>(mem) + align) & ~(align-1));
00064     // Save down the information needed when we call AlignedFree
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         // The maximum no of allocation
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         // Check for stack over flow
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     // Make it non-copy able and non-assignable
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 //  get_aligned_stack() {
00139 //      static AlignedStack<SIMD_ALIGNED_STACK_SIZE, SIMD_ALIGN_BYTE> aStack;
00140 //      return aStack;
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 }   // namespace exmat
00155 
00156 
00157 // Restore the potential macro "free"
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

Generated on Sat May 6 23:11:54 2006 for Exmat by  doxygen 1.4.6-NO