CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DataFormats/GeometrySurface/interface/BlockWipedAllocator.h

Go to the documentation of this file.
00001 #ifndef BlockWipedAllocator_H
00002 #define BlockWipedAllocator_H
00003 
00004 #include<vector>
00005 #include<list>
00006 #include<map>
00007 #include <algorithm>
00008 
00009 #include<boost/bind.hpp>
00010 
00011 // #include<iostream>
00012 
00013 /*  Allocator that never removes single allocations
00014  *  it "wipes" or "clears" the whole allocation when not needed anymore
00015  *  if not wiped it may easily run out of memory
00016  */
00017 class BlockWipedAllocator {
00018 public:
00019   BlockWipedAllocator( std::size_t typeSize,
00020                        std::size_t blockSize);
00021   
00022 
00023   /*  copy constructor clone the allocator and the memory it manages
00024    *  it needs to be reinitialized to avoid pointing to "rh"
00025    *
00026    */
00027   BlockWipedAllocator(BlockWipedAllocator const & rh);
00028 
00029   BlockWipedAllocator& operator=(BlockWipedAllocator const & rh);
00030     
00031 
00032   void * alloc();
00033  
00034   void dealloc(void *);
00035 
00036   // redime memory to the system heap
00037   void clear() const;
00038 
00039   // reset allocator status. does not redime memory
00040   void wipe() const;
00041 
00042 
00043   // longliving (static) local caches: to be reset at wipe
00044   struct LocalCache {
00045     virtual ~LocalCache(){}
00046     virtual void reset()=0;
00047   };
00048 
00049   void registerCache(LocalCache * c) {
00050     localCaches.push_back(c);
00051   }
00052 
00053 private:
00054   std::vector<LocalCache*> localCaches;
00055   
00056 
00057 protected:
00058 
00059   BlockWipedAllocator & me() const;
00060 
00061 public:
00062 
00063   struct Stat {
00064     size_t typeSize;
00065     size_t blockSize;
00066     size_t currentOccupancy;
00067     size_t currentAvailable;
00068     size_t totalAvailable;
00069     size_t nBlocks;
00070     int alive;
00071   };
00072   
00073   Stat stat() const;
00074   
00075 private:
00076   void nextBlock(bool advance);
00077 
00078 
00079   struct Block {
00080     std::size_t m_allocated;
00081     std::vector<unsigned char> m_data;
00082   };
00083 
00084   typedef unsigned char * pointer; 
00085   typedef std::list<Block> Blocks;
00086   typedef Blocks::iterator iterator;
00087   typedef Blocks::const_iterator const_iterator;
00088 
00089 
00090   std::size_t m_typeSize;
00091   std::size_t m_blockSize;
00092   pointer m_next;
00093   iterator m_current;
00094   Blocks m_blocks;
00095 
00096   int m_alive; // for stat purposes
00097 
00098 };
00099 
00100 
00101 class BlockWipedPool {
00102 public:
00103   typedef BlockWipedAllocator Allocator;
00104   typedef std::map<std::size_t, Allocator> Pool; 
00105 
00106   BlockWipedPool(std::size_t blockSize);
00107 
00108   Allocator & allocator( std::size_t typeSize);
00109 
00110   void wipe();
00111 
00112   void clear();
00113 
00114   template<typename Visitor>
00115   void visit(Visitor& visitor) const {
00116     std::for_each(m_pool.begin(),m_pool.end(),boost::bind(&Visitor::visit,visitor,
00117                                                           boost::bind(&Pool::value_type::second,_1)
00118                                                           ));
00119   }
00120 
00121 
00122 private:
00123   std::size_t m_blockSize;
00124   Pool m_pool;
00125 };
00126 
00127 
00128 // singleton
00129 BlockWipedPool & blockWipedPool();
00130 
00131 template<size_t S>
00132 BlockWipedAllocator & blockWipedAllocator() {
00133   static BlockWipedAllocator & local = blockWipedPool().allocator(S);
00134   return local;
00135 }
00136 
00137 template<typename T>
00138 struct LocalCache : public BlockWipedAllocator::LocalCache {
00139   std::auto_ptr<T> ptr;
00140   LocalCache(){ 
00141     blockWipedAllocator<sizeof(T)>().registerCache(this);
00142   }
00143   ~LocalCache(){}
00144   void reset(){ ptr.reset();}
00145 };
00146 
00147 
00148 /*  generaric Basic class
00149  * 
00150  */
00151 class BlockWipedPoolAllocated {
00152 public:
00153   virtual ~BlockWipedPoolAllocated(){}
00154   // instance counter...
00155   static int s_alive;
00156   static void * operator new(size_t s, void * p);
00157   static void * operator new(size_t s);
00158   
00159   static void operator delete(void * p, size_t s);
00160   
00161   static BlockWipedAllocator & allocator(size_t s);
00162   
00163 
00164   static BlockWipedAllocator::Stat stat(size_t s);
00165   
00166   // throw id s_alive!=0???
00167   static void usePool();
00168 
00169 
00170 private:
00171   static bool s_usePool;
00172   // static BlockAllocator * s_allocator;
00173 };
00174 
00175 // below: not used
00176 
00177 /*  Allocator by type
00178  * 
00179  */
00180 template<typename T>
00181 class BlockWipedAllocated {
00182 public:
00183   static void * operator new(size_t) {
00184     return allocator().alloc();
00185   }
00186   
00187   static void operator delete(void * p) {
00188     allocator().dealloc(p);
00189   }
00190   
00191   static BlockWipedAllocator & allocator() {
00192     static BlockWipedAllocator & local = blockWipedPool().allocator(sizeof(T));
00193     return local;
00194   }
00195   
00196 
00197   static BlockWipedAllocator::Stat stat() {
00198     return allocator().stat();
00199   }
00200   
00201 
00202 private:
00203   
00204   // static BlockAllocator * s_allocator;
00205 };
00206 
00207 
00208 /*  Allocator by size
00209  * 
00210  */
00211 template<typename T>
00212 class SizeBlockWipedAllocated {
00213 public:
00214   static void * operator new(size_t) {
00215     return allocator().alloc();
00216   }
00217   
00218   static void operator delete(void * p) {
00219     allocator().dealloc(p);
00220   }
00221   
00222   static BlockWipedAllocator & allocator() {
00223     static BlockWipedAllocator & local = blockWipedAllocator<sizeof(T)>();
00224     return  local;
00225   }
00226   
00227 
00228   static BlockWipedAllocator::Stat stat() {
00229     return allocator().stat();
00230   }
00231   
00232 private:
00233   
00234   // static BlockAllocator * s_allocator;
00235 };
00236 
00237 
00238 #endif // BlockAllocator_H