]> git.ipfire.org Git - thirdparty/squid.git/blame - include/MemPool.h
Bugfix 1750 - support tunnelling of RTSP and other protocols that abuse HTTP by sendi...
[thirdparty/squid.git] / include / MemPool.h
CommitLineData
d96ceb8e 1
2#ifndef _MEM_POOLS_H_
3#define _MEM_POOLS_H_
4
5#include "config.h"
f323a09d 6#include "assert.h"
d96ceb8e 7#include "util.h"
83d8f9f4 8
d96ceb8e 9#include "memMeter.h"
b001e822 10#include "splay.h"
d96ceb8e 11
12#if HAVE_GNUMALLOC_H
13#include <gnumalloc.h>
482aa790 14#elif HAVE_MALLOC_H
d96ceb8e 15#include <malloc.h>
16#endif
17
18#if HAVE_MEMORY_H
19#include <memory.h>
20#endif
21
22#if !M_MMAP_MAX
23#if USE_DLMALLOC
24#define M_MMAP_MAX -4
25#endif
26#endif
27
d96ceb8e 28#define MB ((size_t)1024*1024)
29#define mem_unlimited_size 2 * 1024 * MB
30#define toMB(size) ( ((double) size) / MB )
31#define toKB(size) ( (size + 1024 - 1) / 1024 )
32
33#define MEM_PAGE_SIZE 4096
34#define MEM_CHUNK_SIZE 4096 * 4
35#define MEM_CHUNK_MAX_SIZE 256 * 1024 /* 2MB */
36#define MEM_MIN_FREE 32
37#define MEM_MAX_FREE 65535 /* ushort is max number of items per chunk */
38
b001e822 39class MemImplementingAllocator;
40class MemChunk;
41class MemPoolStats;
83d8f9f4 42
d96ceb8e 43typedef struct _MemPoolGlobalStats MemPoolGlobalStats;
83d8f9f4 44
b001e822 45class MemPoolIterator
83d8f9f4 46{
b001e822 47 public:
48 MemImplementingAllocator *pool;
d96ceb8e 49 MemPoolIterator * next;
50};
51
52/* object to track per-pool cumulative counters */
83d8f9f4 53
b001e822 54class mgb_t
83d8f9f4 55{
b001e822 56 public:
57 mgb_t() : count(0), bytes(0){}
d96ceb8e 58 double count;
59 double bytes;
b001e822 60};
d96ceb8e 61
62/* object to track per-pool memory usage (alloc = inuse+idle) */
83d8f9f4 63
b001e822 64class MemPoolMeter
83d8f9f4 65{
b001e822 66 public:
67 void flush();
d96ceb8e 68 MemMeter alloc;
69 MemMeter inuse;
70 MemMeter idle;
71 mgb_t gb_saved; /* account Allocations */
72 mgb_t gb_osaved; /* history Allocations */
73 mgb_t gb_freed; /* account Free calls */
74};
75
b001e822 76class MemImplementingAllocator;
77
78class MemPools
79{
80 public:
81 static MemPools &GetInstance();
82 MemPools();
83 void init();
84 void flushMeters();
85 MemImplementingAllocator * create(const char *label, size_t obj_size);
86 MemImplementingAllocator * create(const char *label, size_t obj_size, bool const chunked);
87 void setIdleLimit(size_t new_idle_limit);
88 size_t const idleLimit() const;
89 void clean(time_t maxage);
90 void setDefaultPoolChunking(bool const &);
91 MemImplementingAllocator *pools;
92 int mem_idle_limit;
93 int poolCount;
94 bool defaultIsChunked;
95 private:
96 static MemPools *Instance;
97};
98
d96ceb8e 99/* a pool is a [growing] space for objects of the same size */
83d8f9f4 100
b001e822 101class MemAllocator
102{
103public:
104 MemAllocator (char const *aLabel);
105 virtual ~MemAllocator() {}
106 virtual int getStats(MemPoolStats * stats) = 0;
107 virtual MemPoolMeter const &getMeter() const = 0;
108 virtual void *alloc() = 0;
109 virtual void free(void *) = 0;
110 virtual char const *objectType() const;
111 virtual size_t objectSize() const = 0;
112private:
113 const char *label;
114};
115
116/* Support late binding of pool type for allocator agnostic classes */
117class MemAllocatorProxy
83d8f9f4 118{
b001e822 119 public:
120 inline MemAllocatorProxy(char const *aLabel, size_t const &);
121 void *alloc();
122 void free(void *);
123 int inUseCount() const;
124 size_t objectSize() const;
125 MemPoolMeter const &getMeter() const;
126 int getStats(MemPoolStats * stats);
127 char const * objectType() const;
128 private:
129 MemAllocator *getAllocator() const;
d96ceb8e 130 const char *label;
b001e822 131 size_t size;
132 mutable MemAllocator *theAllocator;
133};
134/* help for classes */
135/* Put this in the class */
136#define MEMPROXY_CLASS(CLASS) \
137/* TODO change syntax to allow moving into .cci files */ \
138 inline void *operator new(size_t); \
139 inline void operator delete(void *); \
140 static inline MemAllocatorProxy &Pool()
141
142/* put this in the class .h, or .cci as appropriate */
143#define MEMPROXY_CLASS_INLINE(CLASS) \
144MemAllocatorProxy& CLASS::Pool() \
145{ \
146 static MemAllocatorProxy thePool(#CLASS, sizeof (CLASS)); \
147 return thePool; \
148} \
149\
150void * \
151CLASS::operator new (size_t byteCount) \
152{ \
153 /* derived classes with different sizes must implement their own new */ \
154 assert (byteCount == sizeof (CLASS)); \
155\
156 return Pool().alloc(); \
157} \
158\
159void \
160CLASS::operator delete (void *address) \
161{ \
162 Pool().free(address); \
163}
164
165class MemImplementingAllocator : public MemAllocator
166{
167 public:
168 MemImplementingAllocator(char const *aLabel, size_t aSize);
169 virtual MemPoolMeter const &getMeter() const;
170 virtual MemPoolMeter &getMeter();
171 virtual void flushMetersFull();
172 virtual void flushMeters();
173 virtual void *alloc();
174 virtual void free(void *);
175 virtual bool idleTrigger(int shift) const = 0;
176 virtual void clean(time_t maxage) = 0;
177 /* Hint to the allocator - may be ignored */
178 virtual void setChunkSize(size_t chunksize) {}
179 virtual size_t objectSize() const;
180 protected:
181 virtual void *allocate() = 0;
182 virtual void deallocate(void *) = 0;
183 private:
184 MemPoolMeter meter;
185 public:
186 MemImplementingAllocator *next;
187 public:
188 size_t alloc_calls;
189 size_t free_calls;
d96ceb8e 190 size_t obj_size;
b001e822 191};
192
193class MemPool : public MemImplementingAllocator
194{
195 public:
196 friend class MemChunk;
197 MemPool(const char *label, size_t obj_size);
198 ~MemPool();
199 void convertFreeCacheToChunkFreeCache();
200 virtual void clean(time_t maxage);
201 virtual int getStats(MemPoolStats * stats);
202 void createChunk();
203 void *get();
204 void push(void *obj);
205 protected:
206 virtual void *allocate();
207 virtual void deallocate(void *);
208 public:
209 virtual void setChunkSize(size_t chunksize);
210 virtual bool idleTrigger(int shift) const;
211
d96ceb8e 212 size_t chunk_size;
213 int chunk_capacity;
214 int memPID;
215 int chunkCount;
d96ceb8e 216 size_t inuse;
217 size_t idle;
218 void *freeCache;
219 MemChunk *nextFreeChunk;
220 MemChunk *Chunks;
b001e822 221 Splay<MemChunk *> allChunks;
222};
223
224class MemMalloc : public MemImplementingAllocator
225{
226 public:
227 MemMalloc(char const *label, size_t aSize);
228 virtual bool idleTrigger(int shift) const;
229 virtual void clean(time_t maxage);
230 virtual int getStats(MemPoolStats * stats);
231 protected:
232 virtual void *allocate();
233 virtual void deallocate(void *);
d96ceb8e 234};
235
b001e822 236class MemChunk
83d8f9f4 237{
b001e822 238 public:
239 MemChunk(MemPool *pool);
240 ~MemChunk();
d96ceb8e 241 void *freeList;
242 void *objCache;
243 int inuse_count;
244 MemChunk *nextFreeChunk;
245 MemChunk *next;
246 time_t lastref;
b001e822 247 MemPool *pool;
d96ceb8e 248};
249
b001e822 250class MemPoolStats
83d8f9f4 251{
b001e822 252 public:
253 MemAllocator *pool;
d96ceb8e 254 const char *label;
255 MemPoolMeter *meter;
256 int obj_size;
257 int chunk_capacity;
258 int chunk_size;
259
260 int chunks_alloc;
261 int chunks_inuse;
262 int chunks_partial;
263 int chunks_free;
264
265 int items_alloc;
266 int items_inuse;
267 int items_idle;
268
269 int overhead;
270};
271
83d8f9f4 272struct _MemPoolGlobalStats
273{
d96ceb8e 274 MemPoolMeter *TheMeter;
275
276 int tot_pools_alloc;
277 int tot_pools_inuse;
278 int tot_pools_mempid;
279
280 int tot_chunks_alloc;
281 int tot_chunks_inuse;
282 int tot_chunks_partial;
283 int tot_chunks_free;
284
285 int tot_items_alloc;
286 int tot_items_inuse;
287 int tot_items_idle;
288
289 int tot_overhead;
290 int mem_idle_limit;
291};
292
293#define SIZEOF_CHUNK ( ( sizeof(MemChunk) + sizeof(double) -1) / sizeof(double) ) * sizeof(double);
294
d96ceb8e 295/* Allocator API */
b001e822 296extern MemPoolIterator * memPoolIterate(void);
297extern MemImplementingAllocator * memPoolIterateNext(MemPoolIterator * iter);
298extern void memPoolIterateDone(MemPoolIterator ** iter);
d96ceb8e 299
b001e822 300/* Stats API - not sured how to refactor yet */
301extern int memPoolGetGlobalStats(MemPoolGlobalStats * stats);
d96ceb8e 302
b001e822 303extern int memPoolInUseCount(MemAllocator *);
304extern int memPoolsTotalAllocated(void);
d96ceb8e 305
b001e822 306MemAllocatorProxy::MemAllocatorProxy(char const *aLabel, size_t const &aSize) : label (aLabel), size(aSize), theAllocator (NULL)
307{
308}
d96ceb8e 309
d96ceb8e 310
311#endif /* _MEM_POOLS_H_ */