class MemPoolMeter
{
public:
+ MemPoolMeter();
void flush();
MemMeter alloc;
MemMeter inuse;
MemMeter idle;
- /** account Allocations */
- mgb_t gb_saved;
/** history Allocations */
- mgb_t gb_osaved;
+ mgb_t gb_allocated;
+ mgb_t gb_oallocated;
+
+ /** account Saved Allocations */
+ mgb_t gb_saved;
/** account Free calls */
mgb_t gb_freed;
{
public:
MemImplementingAllocator(char const *aLabel, size_t aSize);
+ ~MemImplementingAllocator();
virtual MemPoolMeter const &getMeter() const;
virtual MemPoolMeter &getMeter();
virtual void flushMetersFull();
public:
size_t alloc_calls;
size_t free_calls;
+ size_t saved_calls;
size_t obj_size;
};
}
calls = alloc_calls;
if (calls) {
- meter.gb_saved.count += calls;
+ meter.gb_allocated.count += calls;
alloc_calls = 0;
}
+ calls = saved_calls;
+ if (calls) {
+ meter.gb_saved.count += calls;
+ saved_calls = 0;
+ }
}
void
MemImplementingAllocator::flushMetersFull()
{
flushMeters();
+ getMeter().gb_allocated.bytes = getMeter().gb_allocated.count * obj_size;
getMeter().gb_saved.bytes = getMeter().gb_saved.count * obj_size;
getMeter().gb_freed.bytes = getMeter().gb_freed.count * obj_size;
}
alloc.level = 0;
inuse.level = 0;
idle.level = 0;
+ gb_allocated.count = 0;
+ gb_allocated.bytes = 0;
+ gb_oallocated.count = 0;
+ gb_oallocated.bytes = 0;
gb_saved.count = 0;
gb_saved.bytes = 0;
gb_freed.count = 0;
gb_freed.bytes = 0;
}
+
+MemPoolMeter::MemPoolMeter()
+{
+ flush();
+}
+
/*
* Updates all pool counters, and recreates TheMeter totals from all pools
*/
memMeterAdd(TheMeter.alloc, pool->getMeter().alloc.level * pool->obj_size);
memMeterAdd(TheMeter.inuse, pool->getMeter().inuse.level * pool->obj_size);
memMeterAdd(TheMeter.idle, pool->getMeter().idle.level * pool->obj_size);
+ TheMeter.gb_allocated.count += pool->getMeter().gb_allocated.count;
TheMeter.gb_saved.count += pool->getMeter().gb_saved.count;
TheMeter.gb_freed.count += pool->getMeter().gb_freed.count;
+ TheMeter.gb_allocated.bytes += pool->getMeter().gb_allocated.bytes;
TheMeter.gb_saved.bytes += pool->getMeter().gb_saved.bytes;
TheMeter.gb_freed.bytes += pool->getMeter().gb_freed.bytes;
}
next(NULL),
alloc_calls(0),
free_calls(0),
+ saved_calls(0),
obj_size(RoundedSize(aSize))
{
- memPID = ++Pool_id_counter;
+ memPID = ++Pool_id_counter;
+
+ MemImplementingAllocator *last_pool;
+
+ assert(aLabel != NULL && aSize);
+ /* Append as Last */
+ for (last_pool = MemPools::GetInstance().pools; last_pool && last_pool->next;)
+ last_pool = last_pool->next;
+ if (last_pool)
+ last_pool->next = this;
+ else
+ MemPools::GetInstance().pools = this;
+}
+
+MemImplementingAllocator::~MemImplementingAllocator()
+{
+ MemImplementingAllocator *find_pool, *prev_pool;
+
+ assert(MemPools::GetInstance().pools != NULL && "Called MemImplementingAllocator::~MemImplementingAllocator, but no pool exists!");
+
+ /* Pool clean, remove it from List and free */
+ for (find_pool = MemPools::GetInstance().pools, prev_pool = NULL; (find_pool && this != find_pool); find_pool = find_pool->next)
+ prev_pool = find_pool;
+ assert(find_pool != NULL && "pool to destroy not found");
+
+ if (prev_pool)
+ prev_pool->next = next;
+ else
+ MemPools::GetInstance().pools = next;
+ --MemPools::GetInstance().poolCount;
}
void
nextFreeChunk = 0;
Chunks = 0;
next = 0;
- MemImplementingAllocator *last_pool;
-
- assert(aLabel != NULL && aSize);
setChunkSize(MEM_CHUNK_SIZE);
-
- /* Append as Last */
- for (last_pool = MemPools::GetInstance().pools; last_pool && last_pool->next;)
- last_pool = last_pool->next;
- if (last_pool)
- last_pool->next = this;
- else
- MemPools::GetInstance().pools = this;
}
MemChunk::~MemChunk()
{
void **Free;
+ saved_calls++;
+
/* first, try cache */
if (freeCache) {
Free = (void **)freeCache;
/* then try perchunk freelist chain */
if (nextFreeChunk == NULL) {
/* no chunk with frees, so create new one */
+ saved_calls--; // compensate for the ++ above
createChunk();
}
/* now we have some in perchunk freelist chain */
MemPoolChunked::~MemPoolChunked()
{
MemChunk *chunk, *fchunk;
- MemImplementingAllocator *find_pool, *prev_pool;
flushMetersFull();
clean(0);
}
/* TODO we should be doing something about the original Chunks pointer here. */
- assert(MemPools::GetInstance().pools != NULL && "Called MemPoolChunked::~MemPoolChunked, but no pool exists!");
-
- /* Pool clean, remove it from List and free */
- for (find_pool = MemPools::GetInstance().pools, prev_pool = NULL; (find_pool && this != find_pool); find_pool = find_pool->next)
- prev_pool = find_pool;
- assert(find_pool != NULL && "pool to destroy not found");
-
- if (prev_pool)
- prev_pool->next = next;
- else
- MemPools::GetInstance().pools = next;
- --MemPools::GetInstance().poolCount;
}
int
MemPoolMeter *pm = mp_st->meter;
const char *delim = "\t ";
+#if HAVE_IOMANIP
+ stream.setf(std::ios_base::fixed);
+#endif
stream << std::setw(20) << std::left << mp_st->label << delim;
stream << std::setw(4) << std::right << mp_st->obj_size << delim;
stream << toKB(mp_st->obj_size * pm->idle.hwater_level) << delim;
/* saved */
stream << (int)pm->gb_saved.count << delim;
- stream << std::setprecision(3) << xpercent(pm->gb_saved.count, AllMeter->gb_saved.count) << delim;
- stream << std::setprecision(3) << xpercent(pm->gb_saved.bytes, AllMeter->gb_saved.bytes) << delim;
- stream << std::setprecision(3) << xdiv(pm->gb_saved.count - pm->gb_osaved.count, xm_deltat) << "\n";
- pm->gb_osaved.count = pm->gb_saved.count;
+ stream << std::setprecision(3) << xpercent(pm->gb_saved.count, AllMeter->gb_allocated.count) << delim;
+ stream << std::setprecision(3) << xpercent(pm->gb_saved.bytes, AllMeter->gb_allocated.bytes) << delim;
+ stream << std::setprecision(3) << xdiv(pm->gb_allocated.count - pm->gb_oallocated.count, xm_deltat) << "\n";
+ pm->gb_oallocated.count = pm->gb_allocated.count;
}
static int
"In Use\t\t\t\t\t"
"Idle\t\t\t"
"Allocations Saved\t\t\t"
- "Hit Rate\t"
+ "Rate\t"
"\n"
" \t (bytes)\t"
"KB/ch\t obj/ch\t"
"(#)\t (KB)\t high (KB)\t high (hrs)\t %alloc\t"
"(#)\t (KB)\t high (KB)\t"
"(#)\t %cnt\t %vol\t"
- "(#) / sec\t"
+ "(#)/sec\t"
"\n";
xm_deltat = current_dtime - xm_time;
xm_time = current_dtime;
if (!mp_stats.pool) /* pool destroyed */
continue;
- if (mp_stats.pool->getMeter().gb_saved.count > 0) /* this pool has been used */
+ if (mp_stats.pool->getMeter().gb_allocated.count > 0) /* this pool has been used */
sortme[npools++] = mp_stats;
else
not_used++;
PoolReport(&mp_stats, mp_total.TheMeter, stream);
/* Cumulative */
- stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.TheMeter->gb_saved.bytes) << "\n";
+ stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.TheMeter->gb_allocated.bytes) << "\n";
/* overhead */
stream << "Current overhead: " << mp_total.tot_overhead << " bytes (" <<
std::setprecision(3) << xpercent(mp_total.tot_overhead, mp_total.TheMeter->inuse.level) << "%)\n";