CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/GeometrySurface/src/BlockWipedAllocator.cc

Go to the documentation of this file.
00001 #include "DataFormats/GeometrySurface/interface/BlockWipedAllocator.h"
00002 
00003 
00004 BlockWipedAllocator::BlockWipedAllocator( std::size_t typeSize,
00005                                           std::size_t blockSize):
00006   m_typeSize(typeSize), m_blockSize(blockSize), m_alive(0){
00007   if (typeSize<32) abort(); // throw std::bad_alloc();
00008   wipe();
00009 }
00010   
00011 
00012 BlockWipedAllocator::BlockWipedAllocator(BlockWipedAllocator const & rh) :
00013   m_typeSize(rh.m_typeSize), m_blockSize(rh.m_blockSize),m_alive(0) {
00014   wipe();
00015 }
00016 
00017 BlockWipedAllocator& BlockWipedAllocator::operator=(BlockWipedAllocator const & rh) {
00018   m_typeSize=rh.m_typeSize; m_blockSize=rh.m_blockSize;
00019   m_alive=0;
00020   wipe();
00021   return *this;
00022 }
00023     
00024 // cannot keep the count as dealloc is never called...
00025 
00026 void * BlockWipedAllocator::alloc() {
00027   m_alive++;
00028   void * ret = m_next;
00029   m_next+=m_typeSize;
00030   Block & block = *m_current;
00031   ++block.m_allocated;
00032   if(m_next==(&block.m_data.back())+1)
00033     nextBlock(true);
00034   return ret;
00035 }
00036   
00037 void BlockWipedAllocator::dealloc(void *) {
00038   m_alive--;
00039 }
00040 
00041 void BlockWipedAllocator::clear() const {
00042   me().m_blocks.clear();
00043   me().wipe();
00044 }
00045 
00046 void BlockWipedAllocator::wipe() const {
00047   // reset caches
00048   std::for_each(localCaches.begin(),localCaches.end(),boost::bind(&LocalCache::reset,_1));
00049 
00050   me().m_current=me().m_blocks.begin();
00051   me().nextBlock(false);
00052 }
00053   
00054 BlockWipedAllocator & BlockWipedAllocator::me() const {
00055   return const_cast<BlockWipedAllocator&>(*this);
00056 }
00057 
00058 BlockWipedAllocator::Stat BlockWipedAllocator::stat() const {
00059   Stat s = { m_typeSize, m_blockSize, (*m_current).m_allocated,
00060              (&*(*m_current).m_data.end()-m_next)/m_typeSize,
00061              std::distance(const_iterator(m_current),m_blocks.end()),
00062              m_blocks.size(), m_alive};
00063   return s;
00064 }
00065 
00066 void BlockWipedAllocator::nextBlock(bool advance) {
00067   if (advance) m_current++;
00068   if (m_current==m_blocks.end()) {
00069     m_blocks.push_back(Block());
00070     m_current=m_blocks.end(); --m_current;
00071   }
00072   m_current->m_data.resize(m_blockSize*m_typeSize);
00073   m_current->m_allocated=0;
00074   m_next = &(m_current->m_data.front());
00075 }
00076 
00077 
00078 BlockWipedPool::BlockWipedPool(std::size_t blockSize) : m_blockSize(blockSize){}
00079 
00080 
00081 BlockWipedPool::Allocator & BlockWipedPool::allocator( std::size_t typeSize) {
00082   Pool::iterator p=m_pool.find(typeSize);
00083   if (p!=m_pool.end()) return (*p).second;
00084   return (*m_pool.insert(std::make_pair(typeSize,Allocator(typeSize, m_blockSize))).first).second;
00085 }
00086 
00087 void BlockWipedPool::wipe() {
00088   std::for_each(m_pool.begin(),m_pool.end(),boost::bind(&Allocator::wipe,
00089                                                         boost::bind(&Pool::value_type::second,_1)
00090                                                         ));
00091 }
00092 
00093 void BlockWipedPool::clear() {
00094   std::for_each(m_pool.begin(),m_pool.end(),boost::bind(&Allocator::clear,
00095                                                         boost::bind(&Pool::value_type::second,_1)
00096                                                         ));
00097 }
00098 
00099 
00100 
00101 
00102 BlockWipedPool & blockWipedPool() {
00103   static BlockWipedPool local(1024);
00104   return local;
00105 }
00106 
00107 
00108 int BlockWipedPoolAllocated::s_alive=0;
00109 bool BlockWipedPoolAllocated::s_usePool=false;
00110 
00111 void BlockWipedPoolAllocated::usePool() { 
00112   // throw id s_alive!=0???
00113   if (0==s_alive) s_usePool=true;
00114 }
00115 
00116 
00117 
00118 void * BlockWipedPoolAllocated::operator new(size_t s) {
00119   s_alive++;
00120   return (s_usePool) ? allocator(s).alloc() : ::operator new(s);
00121 }
00122 
00123 static void *  BlockWipedPoolAllocated::operator new(size_t s, void * p) {
00124   return p;
00125 }
00126 
00127 #include<typeinfo>
00128 #include<iostream>
00129 struct AQ {
00130   virtual ~AQ(){}
00131 };
00132 void BlockWipedPoolAllocated::operator delete(void * p, size_t s) {
00133   if (0==p) return;
00134   // if (s<100) std::cout << typeid(*(BlockWipedPoolAllocated*)(p)).name() << std::endl;
00135   s_alive--;
00136   (s_usePool) ? allocator(s).dealloc(p) : ::operator delete(p);
00137 
00138 }
00139 
00140 BlockWipedAllocator & BlockWipedPoolAllocated::allocator(size_t s) {
00141   return  blockWipedPool().allocator(s);
00142 }
00143 
00144 
00145 BlockWipedAllocator::Stat BlockWipedPoolAllocated::stat(size_t s) {
00146   return allocator(s).stat();
00147 }
00148   
00149 
00150 #include "DataFormats/GeometrySurface/interface/ReferenceCounted.h"
00151 int ReferenceCountedPoolAllocated::s_alive=0;
00152 int ReferenceCountedPoolAllocated::s_referenced=0;