NGSolve  4.9
ngstd/localheap.hpp
00001 #ifndef FILE_LOCALHEAP
00002 #define FILE_LOCALHEAP
00003 
00004 /**************************************************************************/
00005 /* File:   localheap.hpp                                                  */
00006 /* Author: Joachim Schoeberl                                              */
00007 /* Date:   19. Apr. 2000                                                  */
00008 /**************************************************************************/
00009 
00010 
00011 namespace ngstd
00012 {
00013 
00018   class NGS_DLL_HEADER LocalHeapOverflow : public Exception
00019   {
00020   public:
00021     LocalHeapOverflow (size_t size);
00022     virtual ~LocalHeapOverflow ();
00023   };
00024  
00025 
00026 
00034   class LocalHeap
00035   {
00036     char * data;
00037     char * p;
00038     size_t totsize;
00039     bool owner;
00040     const char * name;
00041 
00042   public:
00044     NGS_DLL_HEADER LocalHeap (size_t asize, const char * aname);
00045 
00047     LocalHeap (char * adata, size_t asize, const char  * aname) throw ()
00048     {
00049       totsize = asize;
00050       data = adata;
00051       owner = 0;
00052       // p = data;
00053       name = aname;
00054       CleanUp();
00055     }
00056 
00058     LocalHeap (const LocalHeap & lh2)
00059       : data(lh2.data), p(lh2.p), totsize(lh2.totsize), owner(false)
00060     { ; }
00061 
00062   
00064     ~LocalHeap ()
00065     {
00066       if (owner)
00067         delete [] data;
00068     }
00069   
00071     void CleanUp() throw ()
00072     {
00073       p = data;
00074       // p += (16 - (long(p) & 15) );
00075       p += (16 - (size_t(p) & 15) );
00076     }
00077 
00079     void * GetPointer () throw ()
00080     {
00081       return p;
00082     }
00083 
00085     void CleanUp (void * addr) throw ()
00086     {
00087       p = (char*)addr;
00088     }
00089 
00091     void * Alloc (size_t size) throw (LocalHeapOverflow)
00092     {
00093       char * oldp = p;
00094     
00095       // 16 byte allignment
00096       size += (16 - size % 16);
00097       p += size;
00098 
00099       if ( size_t(p - data) >= totsize )
00100         ThrowException();
00101 
00102       return oldp;
00103     }
00104 
00106     template <typename T>
00107     T * Alloc (size_t size) throw (LocalHeapOverflow)
00108     {
00109       char * oldp = p;
00110       size *= sizeof (T);
00111 
00112       // 16 byte allignment
00113       size += (16 - size % 16);
00114       p += size;
00115 
00116       if ( size_t(p - data) >= totsize )
00117         ThrowException();
00118 
00119       return reinterpret_cast<T*> (oldp);
00120     }
00121 
00122   private:
00124     NGS_DLL_HEADER void ThrowException() throw (LocalHeapOverflow);
00125 
00126   public:
00128     void Free (void * data) throw () 
00129     {
00130       ;
00131     }
00132 
00134     size_t Available () const throw () { return (totsize - (p-data)); }
00135 
00137     LocalHeap Split () const
00138     {
00139 #ifdef _OPENMP
00140       int pieces = omp_get_num_threads();
00141       int i = omp_get_thread_num();
00142 #else
00143       int pieces = 1;
00144       int i = 0;
00145 #endif
00146       size_t freemem = totsize - (p - data);
00147       size_t size_of_piece = freemem / pieces;
00148       return LocalHeap (p + i * size_of_piece, size_of_piece, name);
00149     }
00150   };
00151 
00152 
00153 
00158   template <int S>
00159   class LocalHeapMem : public LocalHeap
00160   {
00161     char mem[S];
00162   public:
00163     LocalHeapMem (const char * aname) throw () : LocalHeap (mem, S, aname) { ; }
00164   };
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00177   class HeapReset
00178   {
00179     LocalHeap & lh;
00180     void * pointer;
00181   public:
00183     HeapReset (LocalHeap & alh) 
00184       : lh(alh), pointer (alh.GetPointer()) { ; }
00185     
00187     ~HeapReset () 
00188     {
00189       lh.CleanUp (pointer);
00190     }
00191   };
00192 
00193 }
00194 
00195 
00196 inline void * operator new (size_t size, ngstd::LocalHeap & lh)  
00197 {
00198   return lh.Alloc(size);
00199 }
00200 
00201 inline void operator delete (void * p, ngstd::LocalHeap & lh)  
00202 {
00203   ; 
00204 }
00205 
00206 
00207 
00208 #endif