NGSolve  5.3
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 * next;
00038     char * p;
00039     size_t totsize;
00040   public:
00041     bool owner;
00042     const char * name;
00043 
00044 #ifdef __MIC__
00045     enum { ALIGN = 64 };
00046 #else
00047     enum { ALIGN = 32 };
00048 #endif  
00049 
00050   public:
00052     NGS_DLL_HEADER LocalHeap (size_t asize, const char * aname = "noname");
00053 
00055     INLINE LocalHeap (char * adata, size_t asize, const char  * aname) throw ()
00056     {
00057       totsize = asize;
00058       data = adata;
00059       next = data + totsize;
00060       owner = 0;
00061       // p = data;
00062       name = aname;
00063       CleanUp();
00064     }
00065 
00067     INLINE LocalHeap (const LocalHeap & lh2)
00068       : data(lh2.data), p(lh2.p), totsize(lh2.totsize), owner(false),
00069         name(lh2.name)
00070     {
00071       next = data + totsize;
00072     }
00073 
00074     INLINE LocalHeap (LocalHeap && lh2)
00075       : data(lh2.data), p(lh2.p), totsize(lh2.totsize), owner(lh2.owner),
00076         name(lh2.name)
00077     {
00078       next = data + totsize;
00079       lh2.owner = false;
00080     }
00081 
00082   
00084     INLINE ~LocalHeap ()
00085     {
00086       if (owner)
00087         delete [] data;
00088     }
00089   
00091     INLINE void CleanUp() throw ()
00092     {
00093       p = data;
00094       // p += (16 - (long(p) & 15) );
00095       p += (ALIGN - (size_t(p) & (ALIGN-1) ) );
00096     }
00097 
00099     INLINE void * GetPointer () throw ()
00100     {
00101       return p;
00102     }
00103 
00105     INLINE void CleanUp (void * addr) throw ()
00106     {
00107       p = (char*)addr;
00108     }
00109 
00111     INLINE void * Alloc (size_t size) // throw (LocalHeapOverflow)
00112     {
00113       char * oldp = p;
00114     
00115       // 16 byte allignment
00116       size += (ALIGN - size % ALIGN);
00117       p += size;
00118 
00119       // if ( size_t(p - data) >= totsize )
00120 #ifndef FULLSPEED
00121       if (p >= next)
00122         ThrowException();
00123 #endif
00124       return oldp;
00125     }
00126 
00128     template <typename T>
00129     INLINE T * Alloc (size_t size) // throw (LocalHeapOverflow)
00130     {
00131       char * oldp = p;
00132       size *= sizeof (T);
00133 
00134       // 16 byte allignment
00135       size += (ALIGN - size % ALIGN);
00136       p += size;
00137 
00138 #ifndef FULLSPEED
00139       if (p >= next)
00140         ThrowException();
00141 #endif
00142 
00143       return reinterpret_cast<T*> (oldp);
00144     }
00145 
00146   private: 
00148 #ifndef __CUDA_ARCH__
00149     NGS_DLL_HEADER void ThrowException(); // __attribute__ ((noreturn));
00150 #else
00151     INLINE void ThrowException() { ; }
00152 #endif
00153 
00154   public:
00156     INLINE void Free (void * data) throw () 
00157     {
00158       ;
00159     }
00160 
00162     INLINE size_t Available () const throw () { return (totsize - (p-data)); }
00163 
00165     INLINE LocalHeap Split () const
00166     {
00167 #ifdef _OPENMP
00168       int pieces = omp_get_num_threads();
00169       int i = omp_get_thread_num();
00170 #else
00171       int pieces = 1;
00172       int i = 0;
00173 #endif
00174       size_t freemem = totsize - (p - data);
00175       size_t size_of_piece = freemem / pieces;
00176       return LocalHeap (p + i * size_of_piece, size_of_piece, name);
00177     }
00178 
00179     INLINE void ClearValues ()
00180     {
00181       for (size_t i = 0; i < totsize; i++) data[i] = 47;
00182     }
00183 
00184     INLINE size_t UsedSize ()
00185     {
00186       for (size_t i = totsize-1; i != 0; i--)
00187         if (data[i] != 47) return i;
00188       return 0;
00189     }
00190   };
00191 
00192 
00193 
00198   template <int S>
00199   class LocalHeapMem : public LocalHeap
00200   {
00201     char mem[S];
00202   public:
00203     INLINE LocalHeapMem (const char * aname) throw () : LocalHeap (mem, S, aname) { ; }
00204   };
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00217   class HeapReset
00218   {
00219     LocalHeap & lh;
00220     void * pointer;
00221   public:
00223     INLINE HeapReset (LocalHeap & alh) 
00224       : lh(alh), pointer (alh.GetPointer()) { ; }
00225     
00227     INLINE ~HeapReset () 
00228     {
00229       lh.CleanUp (pointer);
00230     }
00231   };
00232 
00233 }
00234 
00235 
00236 INLINE void * operator new (size_t size, ngstd::LocalHeap & lh)  
00237 {
00238   return lh.Alloc(size);
00239 }
00240 
00241 INLINE void * operator new [] (size_t size, ngstd::LocalHeap & lh)  
00242 {
00243   return lh.Alloc(size);
00244 }
00245 
00246 INLINE void operator delete (void * p, ngstd::LocalHeap & lh)  
00247 {
00248   ; 
00249 }
00250 
00251 INLINE void operator delete [] (void * p, ngstd::LocalHeap & lh)  
00252 {
00253   ; 
00254 }
00255 
00256 
00257 
00258 
00259 #endif