Go to the documentation of this file.00001 #ifndef BlockWipedAllocator_H
00002 #define BlockWipedAllocator_H
00003
00004 #include<vector>
00005 #include<list>
00006
00007 #include <ext/hash_map>
00008
00009 #include <algorithm>
00010
00011 #include<boost/bind.hpp>
00012
00013 #include "FWCore/Utilities/interface/Visibility.h"
00014
00015
00016
00017
00018
00019
00020
00021
00022 class BlockWipedAllocator {
00023 public:
00024 BlockWipedAllocator( std::size_t typeSize,
00025 std::size_t blockSize,
00026 std::size_t maxRecycle
00027 );
00028
00029
00030
00031
00032
00033
00034 BlockWipedAllocator(BlockWipedAllocator const & rh);
00035
00036 BlockWipedAllocator& operator=(BlockWipedAllocator const & rh);
00037
00038
00039 void * alloc();
00040
00041 void dealloc(void *);
00042
00043
00044 void clear() const;
00045
00046
00047 void wipe(bool force=true) const;
00048
00049
00050
00051 struct LocalCache {
00052 virtual ~LocalCache(){}
00053 virtual void reset()=0;
00054 };
00055
00056 void registerCache(LocalCache * c) {
00057 localCaches.push_back(c);
00058 }
00059
00060 private:
00061 std::vector<LocalCache*> localCaches;
00062 std::vector<void *> recycled;
00063
00064
00065 protected:
00066
00067 BlockWipedAllocator & me() const;
00068
00069 public:
00070
00071 struct Stat {
00072 size_t typeSize;
00073 size_t blockSize;
00074 size_t currentOccupancy;
00075 size_t currentAvailable;
00076 size_t totalAvailable;
00077 size_t nBlocks;
00078 int alive;
00079 };
00080
00081 Stat stat() const;
00082
00083 private:
00084 void nextBlock(bool advance) dso_internal;
00085
00086
00087 struct Block {
00088 std::size_t m_allocated;
00089 std::vector<unsigned char> m_data;
00090 };
00091
00092 typedef unsigned char * pointer;
00093 typedef std::list<Block> Blocks;
00094 typedef Blocks::iterator iterator;
00095 typedef Blocks::const_iterator const_iterator;
00096
00097
00098 std::size_t m_typeSize;
00099 std::size_t m_blockSize;
00100 std::size_t m_maxRecycle;
00101 pointer m_next;
00102 iterator m_current;
00103 Blocks m_blocks;
00104
00105 int m_alive;
00106
00107 };
00108
00109
00110 class BlockWipedPool {
00111 public:
00112 typedef BlockWipedAllocator Allocator;
00113
00114 typedef __gnu_cxx::hash_map<std::size_t, Allocator> Pool;
00115
00116 BlockWipedPool(std::size_t blockSize, std::size_t maxRecycle);
00117
00118 Allocator & allocator( std::size_t typeSize);
00119
00120 void wipe(bool force=true);
00121
00122 void clear();
00123
00124 template<typename Visitor>
00125 void visit(Visitor& visitor) const {
00126 std::for_each(m_pool.begin(),m_pool.end(),boost::bind(&Visitor::visit,visitor,
00127 boost::bind(&Pool::value_type::second,_1)
00128 ));
00129 }
00130
00131
00132 private:
00133 std::size_t m_blockSize;
00134 std::size_t m_maxRecycle;
00135 Pool m_pool;
00136 Allocator * m_last;
00137 std::size_t m_lastSize;
00138 };
00139
00140
00141
00142
00143
00144
00145 class BlockWipedPoolAllocated {
00146 public:
00147 virtual ~BlockWipedPoolAllocated(){}
00148
00149 static int s_alive;
00150 static void * operator new(size_t s, void * p);
00151 static void * operator new(size_t s);
00152
00153 static void operator delete(void * p, size_t s);
00154
00155 static BlockWipedAllocator & allocator(size_t s);
00156
00157
00158 static BlockWipedAllocator::Stat stat(size_t s);
00159
00160
00161 static void usePool();
00162
00163
00164
00165 static bool s_usePool;
00166
00167 };
00168
00169
00170 BlockWipedPool & blockWipedPool(BlockWipedPool * p=0);
00171
00172 template<size_t S>
00173 BlockWipedAllocator & blockWipedAllocator() {
00174 static BlockWipedAllocator & local = blockWipedPool().allocator(S);
00175 return local;
00176 }
00177
00178 template<typename T>
00179 struct LocalCache : public BlockWipedAllocator::LocalCache {
00180 std::auto_ptr<T> ptr;
00181 LocalCache(){
00182 if (BlockWipedPoolAllocated::s_usePool)
00183 blockWipedAllocator<sizeof(T)>().registerCache(this);
00184 }
00185 ~LocalCache(){}
00186 void reset(){ ptr.reset();}
00187 };
00188
00189
00190
00191
00192
00193 template<typename T>
00194 class BlockWipedAllocated {
00195 public:
00196 static void * operator new(size_t s) {
00197 BlockWipedPoolAllocated::s_alive++;
00198 return (BlockWipedPoolAllocated::s_usePool) ? allocator().alloc() : ::operator new(s);
00199 }
00200
00201 static void operator delete(void * p) {
00202 if (0==p) return;
00203 BlockWipedPoolAllocated::s_alive--;
00204 return (BlockWipedPoolAllocated::s_usePool) ? allocator().dealloc(p) : ::operator delete(p);
00205 }
00206
00207 static void * operator new(size_t s, void * p) {
00208 return p;
00209 }
00210
00211
00212 static BlockWipedAllocator & allocator() {
00213 static BlockWipedAllocator & local = blockWipedPool().allocator(sizeof(T));
00214 return local;
00215 }
00216
00217
00218 static BlockWipedAllocator::Stat stat() {
00219 return allocator().stat();
00220 }
00221
00222
00223 private:
00224
00225
00226 };
00227
00228
00229
00230
00231
00232 template<typename T>
00233 class SizeBlockWipedAllocated {
00234 public:
00235 static void * operator new(size_t) {
00236 return allocator().alloc();
00237 }
00238
00239 static void operator delete(void * p) {
00240 allocator().dealloc(p);
00241 }
00242
00243 static BlockWipedAllocator & allocator() {
00244 static BlockWipedAllocator & local = blockWipedAllocator<sizeof(T)>();
00245 return local;
00246 }
00247
00248
00249 static BlockWipedAllocator::Stat stat() {
00250 return allocator().stat();
00251 }
00252
00253 private:
00254
00255
00256 };
00257
00258
00259 #endif // BlockAllocator_H