extern const char *gb_to_str(const gb_t *);
extern void gb_flush(gb_t *); /* internal, do not use this */
-/*
- * Returns the amount of known allocated memory
- */
-int statMemoryAccounted(void);
-
SQUIDCEXTERN unsigned int RoundTo(const unsigned int num, const unsigned int what);
#endif /* SQUID_UTIL_H */
getfullhostname.c \
heap.c \
radix.c \
- stub_memaccount.c \
util.c \
xusleep.c
+++ /dev/null
-/*
- * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-/* Stub function for programs not implementing statMemoryAccounted */
-#include "squid.h"
-#include "util.h"
-
-int
-statMemoryAccounted(void)
-{
- return -1;
-}
-
* fill the given object with statistical data about pool
* \returns Number of objects in use, ie. allocated.
*/
- virtual int getStats(MemPoolStats *, int accumulate = 0) = 0;
+ virtual size_t getStats(PoolStats &) = 0;
virtual PoolMeter const &getMeter() const = 0;
#include "mem/AllocatorProxy.h"
#include "mem/Meter.h"
#include "mem/Pool.h"
+#include "mem/Stats.h"
void *
Mem::AllocatorProxy::alloc()
return getAllocator()->getMeter();
}
-int
-Mem::AllocatorProxy::getStats(MemPoolStats * stats)
+size_t
+Mem::AllocatorProxy::getStats(PoolStats &stats)
{
return getAllocator()->getStats(stats);
}
// XXX: remove AllocatorProxy.h include from mem/forward.h
namespace Mem {
class Allocator;
+class PoolStats;
}
-class MemPoolStats;
/**
* \hideinitializer
* \param stats Object to be filled with statistical data about pool.
* \retval Number of objects in use, ie. allocated.
*/
- int getStats(MemPoolStats * stats);
+ size_t getStats(PoolStats &stats);
void zeroBlocks(bool doIt);
PoolMalloc.cc \
PoolMalloc.h \
PoolingAllocator.h \
+ Stats.cc \
+ Stats.h \
old_api.cc
# a bare-bones implementation of few libmem.la APIs sufficient for helpers use
#include "squid.h"
#include "mem/PoolChunked.h"
#include "mem/PoolMalloc.h"
+#include "mem/Stats.h"
#include <cassert>
#include <cstring>
extern time_t squid_curtime;
-static Mem::PoolMeter TheMeter;
-static MemPoolIterator Iterator;
-static int Pool_id_counter = 0;
+Mem::PoolMeter TheMeter;
MemPools &
MemPools::GetInstance()
return *Instance;
}
-MemPoolIterator *
-memPoolIterate(void)
-{
- Iterator.pool = MemPools::GetInstance().pools;
- return &Iterator;
-}
-
-void
-memPoolIterateDone(MemPoolIterator ** iter)
-{
- assert(iter != nullptr);
- Iterator.pool = nullptr;
- *iter = nullptr;
-}
-
-MemImplementingAllocator *
-memPoolIterateNext(MemPoolIterator * iter)
-{
- MemImplementingAllocator *pool;
- assert(iter != nullptr);
-
- pool = iter->pool;
- if (!pool)
- return nullptr;
-
- iter->pool = pool->next;
- return pool;
-}
-
/* Change the default value of defaultIsChunked to override
* all pools - including those used before main() starts where
* MemPools::GetInstance().setDefaultPoolChunking() can be called.
MemImplementingAllocator *
MemPools::create(const char *label, size_t obj_size)
{
- ++poolCount;
+ // TODO Use ref-counted Pointer for pool lifecycle management
+ // that is complicated by all the global static pool pointers.
+ // For now leak these Allocator descendants on shutdown.
+
+ MemImplementingAllocator *newPool;
if (defaultIsChunked)
- return new MemPoolChunked (label, obj_size);
+ newPool = new MemPoolChunked(label, obj_size);
else
- return new MemPoolMalloc (label, obj_size);
+ newPool = new MemPoolMalloc(label, obj_size);
+ pools.push_back(newPool);
+ return pools.back();
}
void
{
TheMeter.flush();
- MemPoolIterator *iter = memPoolIterate();
- while (MemImplementingAllocator *pool = memPoolIterateNext(iter)) {
+ for (const auto pool: pools) {
pool->flushMetersFull();
// are these TheMeter grow() operations or accumulated volumes ?
TheMeter.alloc += pool->getMeter().alloc.currentLevel() * pool->obj_size;
TheMeter.gb_saved.bytes += pool->getMeter().gb_saved.bytes;
TheMeter.gb_freed.bytes += pool->getMeter().gb_freed.bytes;
}
- memPoolIterateDone(&iter);
}
void *
if (TheMeter.idle.currentLevel() > idleLimit())
maxage = shift = 0;
- MemImplementingAllocator *pool;
- MemPoolIterator *iter;
- iter = memPoolIterate();
- while ((pool = memPoolIterateNext(iter)))
+ for (const auto pool: pools) {
if (pool->idleTrigger(shift))
pool->clean(maxage);
- memPoolIterateDone(&iter);
-}
-
-/* Persistent Pool stats. for GlobalStats accumulation */
-static MemPoolStats pp_stats;
-
-/*
- * Totals statistics is returned
- */
-int
-memPoolGetGlobalStats(MemPoolGlobalStats * stats)
-{
- int pools_inuse = 0;
- MemPoolIterator *iter;
-
- memset(stats, 0, sizeof(MemPoolGlobalStats));
- memset(&pp_stats, 0, sizeof(MemPoolStats));
-
- MemPools::GetInstance().flushMeters(); /* recreate TheMeter */
-
- /* gather all stats for Totals */
- iter = memPoolIterate();
- while (const auto pool = memPoolIterateNext(iter)) {
- if (pool->getStats(&pp_stats, 1) > 0)
- ++pools_inuse;
}
- memPoolIterateDone(&iter);
-
- stats->TheMeter = &TheMeter;
-
- stats->tot_pools_alloc = MemPools::GetInstance().poolCount;
- stats->tot_pools_inuse = pools_inuse;
- stats->tot_pools_mempid = Pool_id_counter;
-
- stats->tot_chunks_alloc = pp_stats.chunks_alloc;
- stats->tot_chunks_inuse = pp_stats.chunks_inuse;
- stats->tot_chunks_partial = pp_stats.chunks_partial;
- stats->tot_chunks_free = pp_stats.chunks_free;
- stats->tot_items_alloc = pp_stats.items_alloc;
- stats->tot_items_inuse = pp_stats.items_inuse;
- stats->tot_items_idle = pp_stats.items_idle;
-
- stats->tot_overhead += pp_stats.overhead + MemPools::GetInstance().poolCount * sizeof(Mem::Allocator *);
- stats->mem_idle_limit = MemPools::GetInstance().idleLimit();
-
- return pools_inuse;
-}
-
-int
-memPoolsTotalAllocated(void)
-{
- MemPoolGlobalStats stats;
- memPoolGetGlobalStats(&stats);
- return stats.TheMeter->alloc.currentLevel();
}
MemImplementingAllocator::MemImplementingAllocator(char const * const aLabel, const size_t aSize):
Mem::Allocator(aLabel),
- next(nullptr),
alloc_calls(0),
free_calls(0),
saved_calls(0),
obj_size(RoundedSize(aSize))
{
- memPID = ++Pool_id_counter;
-
- MemImplementingAllocator *last_pool;
-
assert(aLabel != nullptr && 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;
-
- /* Abort if the associated pool doesn't exist */
- assert(MemPools::GetInstance().pools != nullptr );
-
- /* Pool clean, remove it from List and free */
- for (find_pool = MemPools::GetInstance().pools, prev_pool = nullptr; (find_pool && this != find_pool); find_pool = find_pool->next)
- prev_pool = find_pool;
-
- /* make sure that we found the pool to destroy */
- assert(find_pool != nullptr);
-
- if (prev_pool)
- prev_pool->next = next;
- else
- MemPools::GetInstance().pools = next;
- --MemPools::GetInstance().poolCount;
}
Mem::PoolMeter const &
#include "mem/Meter.h"
#include "util.h"
+#include <list>
#if HAVE_GNUMALLOC_H
#include <gnumalloc.h>
#elif HAVE_MALLOC_H
#define MEM_MAX_FREE 65535 /* unsigned short is max number of items per chunk */
class MemImplementingAllocator;
-class MemPoolStats;
-/// \ingroup MemPoolsAPI
-/// TODO: Kill this typedef for C++
-typedef struct _MemPoolGlobalStats MemPoolGlobalStats;
-
-/// \ingroup MemPoolsAPI
-class MemPoolIterator
-{
-public:
- MemImplementingAllocator *pool;
- MemPoolIterator * next;
-};
-
-class MemImplementingAllocator;
+/// memory usage totals as of latest MemPools::flushMeters() event
+extern Mem::PoolMeter TheMeter;
/// \ingroup MemPoolsAPI
class MemPools
void flushMeters();
/**
- \param label Name for the pool. Displayed in stats.
- \param obj_size Size of elements in MemPool.
+ * Create an allocator with given name to allocate fixed-size objects
+ * of the specified size.
*/
- MemImplementingAllocator * create(const char *label, size_t obj_size);
+ MemImplementingAllocator *create(const char *, size_t);
/**
* Sets upper limit in bytes to amount of free ram kept in pools. This is
void setDefaultPoolChunking(bool const &);
- MemImplementingAllocator *pools = nullptr;
- int poolCount = 0;
+ std::list<MemImplementingAllocator *> pools;
bool defaultIsChunked = false;
private:
typedef Mem::PoolMeter PoolMeter; // TODO remove
MemImplementingAllocator(char const *aLabel, size_t aSize);
- virtual ~MemImplementingAllocator();
virtual PoolMeter &getMeter();
virtual void flushMetersFull();
virtual void *allocate() = 0;
virtual void deallocate(void *, bool aggressive) = 0;
PoolMeter meter;
- int memPID;
-public:
- MemImplementingAllocator *next;
public:
size_t alloc_calls;
size_t free_calls;
size_t obj_size;
};
-/// \ingroup MemPoolsAPI
-class MemPoolStats
-{
-public:
- typedef Mem::PoolMeter PoolMeter; // TODO remove
- typedef Mem::Allocator Allocator; // TODO remove
-
- Allocator *pool;
- const char *label;
- PoolMeter *meter;
- int obj_size;
- int chunk_capacity;
- int chunk_size;
-
- int chunks_alloc;
- int chunks_inuse;
- int chunks_partial;
- int chunks_free;
-
- int items_alloc;
- int items_inuse;
- int items_idle;
-
- int overhead;
-};
-
-/// \ingroup MemPoolsAPI
-/// TODO: Classify and add constructor/destructor to initialize properly.
-struct _MemPoolGlobalStats {
- typedef Mem::PoolMeter PoolMeter; // TODO remove
-
- PoolMeter *TheMeter;
-
- int tot_pools_alloc;
- int tot_pools_inuse;
- int tot_pools_mempid;
-
- int tot_chunks_alloc;
- int tot_chunks_inuse;
- int tot_chunks_partial;
- int tot_chunks_free;
-
- int tot_items_alloc;
- int tot_items_inuse;
- int tot_items_idle;
-
- int tot_overhead;
- ssize_t mem_idle_limit;
-};
-
-/// \ingroup MemPoolsAPI
/// Creates a named MemPool of elements with the given size
#define memPoolCreate MemPools::GetInstance().create
-/* Allocator API */
-/**
- \ingroup MemPoolsAPI
- * Initialise iteration through all of the pools.
- * \returns Iterator for use by memPoolIterateNext() and memPoolIterateDone()
- */
-extern MemPoolIterator * memPoolIterate(void);
-
-/**
- \ingroup MemPoolsAPI
- * Get next pool pointer, until getting NULL pointer.
- */
-extern MemImplementingAllocator * memPoolIterateNext(MemPoolIterator * iter);
-
-/**
- \ingroup MemPoolsAPI
- * Should be called after finished with iterating through all pools.
- */
-extern void memPoolIterateDone(MemPoolIterator ** iter);
-
-/**
- \ingroup MemPoolsAPI
- *
- * Fills a MemPoolGlobalStats with statistical data about overall
- * usage for all pools.
- *
- * \param stats Object to be filled with statistical data.
- *
- * \return Number of pools that have at least one object in use.
- * Ie. number of dirty pools.
- */
-extern int memPoolGetGlobalStats(MemPoolGlobalStats * stats);
-
-/// \ingroup MemPoolsAPI
-extern int memPoolsTotalAllocated(void);
-
#endif /* _MEM_POOL_H_ */
#include "squid.h"
#include "mem/PoolChunked.h"
+#include "mem/Stats.h"
#include <cassert>
#include <cstring>
return meter.idle.currentLevel() > (chunk_capacity << shift);
}
-/*
- * Update MemPoolStats struct for single pool
- */
-int
-MemPoolChunked::getStats(MemPoolStats * stats, int accumulate)
+size_t
+MemPoolChunked::getStats(Mem::PoolStats &stats)
{
MemChunk *chunk;
int chunks_free = 0;
int chunks_partial = 0;
- if (!accumulate) /* need skip memset for GlobalStats accumulation */
- memset(stats, 0, sizeof(MemPoolStats));
-
clean((time_t) 555555); /* don't want to get chunks released before reporting */
- stats->pool = this;
- stats->label = objectType();
- stats->meter = &meter;
- stats->obj_size = obj_size;
- stats->chunk_capacity = chunk_capacity;
+ stats.pool = this;
+ stats.label = objectType();
+ stats.meter = &meter;
+ stats.obj_size = obj_size;
+ stats.chunk_capacity = chunk_capacity;
/* gather stats for each Chunk */
chunk = Chunks;
chunk = chunk->next;
}
- stats->chunks_alloc += chunkCount;
- stats->chunks_inuse += chunkCount - chunks_free;
- stats->chunks_partial += chunks_partial;
- stats->chunks_free += chunks_free;
+ stats.chunks_alloc += chunkCount;
+ stats.chunks_inuse += chunkCount - chunks_free;
+ stats.chunks_partial += chunks_partial;
+ stats.chunks_free += chunks_free;
- stats->items_alloc += meter.alloc.currentLevel();
- stats->items_inuse += meter.inuse.currentLevel();
- stats->items_idle += meter.idle.currentLevel();
+ stats.items_alloc += meter.alloc.currentLevel();
+ stats.items_inuse += meter.inuse.currentLevel();
+ stats.items_idle += meter.idle.currentLevel();
- stats->overhead += sizeof(MemPoolChunked) + chunkCount * sizeof(MemChunk) + strlen(objectType()) + 1;
+ stats.overhead += sizeof(MemPoolChunked) + chunkCount * sizeof(MemChunk) + strlen(objectType()) + 1;
return meter.inuse.currentLevel();
}
~MemPoolChunked();
void convertFreeCacheToChunkFreeCache();
virtual void clean(time_t maxage);
-
void createChunk();
void *get();
void push(void *obj);
/* Mem::Allocator API */
- virtual int getStats(MemPoolStats *, int);
+ virtual size_t getStats(Mem::PoolStats &);
virtual int getInUseCount();
virtual void setChunkSize(size_t);
#include "squid.h"
#include "mem/PoolMalloc.h"
+#include "mem/Stats.h"
#include <cassert>
#include <cstring>
}
/* TODO extract common logic to MemAllocate */
-int
-MemPoolMalloc::getStats(MemPoolStats * stats, int accumulate)
+size_t
+MemPoolMalloc::getStats(Mem::PoolStats &stats)
{
- if (!accumulate) /* need skip memset for GlobalStats accumulation */
- memset(stats, 0, sizeof(MemPoolStats));
-
- stats->pool = this;
- stats->label = objectType();
- stats->meter = &meter;
- stats->obj_size = obj_size;
- stats->chunk_capacity = 0;
-
- stats->chunks_alloc += 0;
- stats->chunks_inuse += 0;
- stats->chunks_partial += 0;
- stats->chunks_free += 0;
-
- stats->items_alloc += meter.alloc.currentLevel();
- stats->items_inuse += meter.inuse.currentLevel();
- stats->items_idle += meter.idle.currentLevel();
-
- stats->overhead += sizeof(MemPoolMalloc) + strlen(objectType()) + 1;
+ stats.pool = this;
+ stats.label = objectType();
+ stats.meter = &meter;
+ stats.obj_size = obj_size;
+ stats.chunk_capacity = 0;
+
+ stats.chunks_alloc += 0;
+ stats.chunks_inuse += 0;
+ stats.chunks_partial += 0;
+ stats.chunks_free += 0;
+
+ stats.items_alloc += meter.alloc.currentLevel();
+ stats.items_inuse += meter.inuse.currentLevel();
+ stats.items_idle += meter.idle.currentLevel();
+
+ stats.overhead += sizeof(MemPoolMalloc) + strlen(objectType()) + 1;
return meter.inuse.currentLevel();
}
virtual void clean(time_t maxage);
/* Mem::Allocator API */
- virtual int getStats(MemPoolStats *, int);
+ virtual size_t getStats(Mem::PoolStats &);
virtual int getInUseCount();
protected:
--- /dev/null
+/*
+ * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "mem/Pool.h"
+#include "mem/Stats.h"
+
+size_t
+Mem::GlobalStats(PoolStats &stats)
+{
+ MemPools::GetInstance().flushMeters();
+
+ stats.meter = &TheMeter;
+ stats.label = "Total";
+ stats.obj_size = 1;
+ stats.overhead += sizeof(MemPools);
+
+ /* gather all stats for Totals */
+ size_t pools_inuse = 0;
+ for (const auto pool: MemPools::GetInstance().pools) {
+ if (pool->getStats(stats) > 0)
+ ++pools_inuse;
+ stats.overhead += sizeof(Allocator *);
+ }
+
+ return pools_inuse;
+}
--- /dev/null
+/*
+ * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID__SRC_MEM_STATS_H
+#define SQUID__SRC_MEM_STATS_H
+
+#include "mem/forward.h"
+
+namespace Mem
+{
+
+class PoolStats
+{
+public:
+ Allocator *pool = nullptr;
+ const char *label = nullptr;
+ PoolMeter *meter = nullptr;
+ int obj_size = 0;
+ int chunk_capacity = 0;
+ int chunk_size = 0;
+
+ int chunks_alloc = 0;
+ int chunks_inuse = 0;
+ int chunks_partial = 0;
+ int chunks_free = 0;
+
+ int items_alloc = 0;
+ int items_inuse = 0;
+ int items_idle = 0;
+
+ int overhead = 0;
+};
+
+/**
+ * Fills a Mem::PoolStats with statistical data about overall
+ * usage for all pools.
+ *
+ * \return Number of pools that have at least one object in use.
+ * Ie. number of dirty pools.
+ */
+extern size_t GlobalStats(PoolStats &);
+
+} // namespace Mem
+
+#endif /* SQUID__SRC_MEM_STATS_H */
#include <iosfwd>
class StoreEntry;
-class MemPoolStats;
/// Memory Management
namespace Mem
{
class Meter;
class PoolMeter;
+class PoolStats;
void Init();
void Stats(StoreEntry *);
void CleanIdlePools(void *unused);
void Report(std::ostream &);
-void PoolReport(const MemPoolStats *, const PoolMeter *, std::ostream &);
+void PoolReport(const PoolStats *, const PoolMeter *, std::ostream &);
};
extern const size_t squidSystemPageSize;
return Alive;
}
-int
-Mem::AllocatorProxy::getStats(MemPoolStats *)
+size_t
+Mem::AllocatorProxy::getStats(PoolStats &)
{
return Alive;
}
#include "mem/forward.h"
#include "mem/Meter.h"
#include "mem/Pool.h"
+#include "mem/Stats.h"
#include "MemBuf.h"
#include "mgr/Registration.h"
#include "SquidConfig.h"
void
memClean(void)
{
- MemPoolGlobalStats stats;
if (Config.MemPools.limit > 0) // do not reset if disabled or same
MemPools::GetInstance().setIdleLimit(0);
MemPools::GetInstance().clean(0);
- memPoolGetGlobalStats(&stats);
- if (stats.tot_items_inuse)
- debugs(13, 2, "memCleanModule: " << stats.tot_items_inuse <<
- " items in " << stats.tot_chunks_inuse << " chunks and " <<
- stats.tot_pools_inuse << " pools are left dirty");
+ Mem::PoolStats stats;
+ const auto poolsInUse = Mem::GlobalStats(stats);
+ if (stats.items_inuse) {
+ debugs(13, 2, stats.items_inuse <<
+ " items in " << stats.chunks_inuse << " chunks and " <<
+ poolsInUse << " pools are left dirty");
+ }
}
int
}
void
-Mem::PoolReport(const MemPoolStats * mp_st, const PoolMeter * AllMeter, std::ostream &stream)
+Mem::PoolReport(const PoolStats *mp_st, const PoolMeter *AllMeter, std::ostream &stream)
{
int excess = 0;
int needed = 0;
pm->gb_oallocated.count = pm->gb_allocated.count;
}
-static int
-MemPoolReportSorter(const void *a, const void *b)
-{
- const MemPoolStats *A = (MemPoolStats *) a;
- const MemPoolStats *B = (MemPoolStats *) b;
-
- // use this to sort on %Total Allocated
- //
- double pa = (double) A->obj_size * A->meter->alloc.currentLevel();
- double pb = (double) B->obj_size * B->meter->alloc.currentLevel();
-
- if (pa > pb)
- return -1;
-
- if (pb > pa)
- return 1;
-
- return 0;
-}
-
void
Mem::Report(std::ostream &stream)
{
static char buf[64];
- static MemPoolStats mp_stats;
- static MemPoolGlobalStats mp_total;
int not_used = 0;
- MemPoolIterator *iter;
/* caption */
stream << "Current memory usage:\n";
xm_time = current_dtime;
/* Get stats for Totals report line */
- memPoolGetGlobalStats(&mp_total);
+ PoolStats mp_total;
+ const auto poolsInUse = GlobalStats(mp_total);
- MemPoolStats *sortme = (MemPoolStats *) xcalloc(mp_total.tot_pools_alloc,sizeof(*sortme));
- int npools = 0;
+ std::vector<PoolStats> usedPools;
+ usedPools.reserve(poolsInUse);
/* main table */
- iter = memPoolIterate();
-
- while (const auto pool = memPoolIterateNext(iter)) {
- pool->getStats(&mp_stats);
+ for (const auto pool : MemPools::GetInstance().pools) {
+ PoolStats mp_stats;
+ pool->getStats(mp_stats);
- if (!mp_stats.pool) /* pool destroyed */
- continue;
-
- if (mp_stats.pool->getMeter().gb_allocated.count > 0) {
- /* this pool has been used */
- sortme[npools] = mp_stats;
- ++npools;
- } else {
+ if (mp_stats.pool->getMeter().gb_allocated.count > 0)
+ usedPools.emplace_back(mp_stats);
+ else
++not_used;
- }
}
- memPoolIterateDone(&iter);
-
- qsort(sortme, npools, sizeof(*sortme), MemPoolReportSorter);
+ // sort on %Total Allocated (largest first)
+ std::sort(usedPools.begin(), usedPools.end(), [](const PoolStats &a, const PoolStats &b) {
+ return (double(a.obj_size) * a.meter->alloc.currentLevel()) > (double(b.obj_size) * b.meter->alloc.currentLevel());
+ });
- for (int i = 0; i< npools; ++i) {
- PoolReport(&sortme[i], mp_total.TheMeter, stream);
+ for (const auto &pool: usedPools) {
+ PoolReport(&pool, mp_total.meter, stream);
}
- xfree(sortme);
-
- mp_stats.pool = nullptr;
- mp_stats.label = "Total";
- mp_stats.meter = mp_total.TheMeter;
- mp_stats.obj_size = 1;
- mp_stats.chunk_capacity = 0;
- mp_stats.chunk_size = 0;
- mp_stats.chunks_alloc = mp_total.tot_chunks_alloc;
- mp_stats.chunks_inuse = mp_total.tot_chunks_inuse;
- mp_stats.chunks_partial = mp_total.tot_chunks_partial;
- mp_stats.chunks_free = mp_total.tot_chunks_free;
- mp_stats.items_alloc = mp_total.tot_items_alloc;
- mp_stats.items_inuse = mp_total.tot_items_inuse;
- mp_stats.items_idle = mp_total.tot_items_idle;
- mp_stats.overhead = mp_total.tot_overhead;
-
- PoolReport(&mp_stats, mp_total.TheMeter, stream);
+ PoolReport(&mp_total, mp_total.meter, stream);
/* Cumulative */
- stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.TheMeter->gb_allocated.bytes) << "\n";
+ stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.meter->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.currentLevel()) << "%)\n";
+ stream << "Current overhead: " << mp_total.overhead << " bytes (" <<
+ std::setprecision(3) << xpercent(mp_total.overhead, mp_total.meter->inuse.currentLevel()) << "%)\n";
/* limits */
- if (mp_total.mem_idle_limit >= 0)
- stream << "Idle pool limit: " << std::setprecision(2) << toMB(mp_total.mem_idle_limit) << " MB\n";
+ if (MemPools::GetInstance().idleLimit() >= 0)
+ stream << "Idle pool limit: " << std::setprecision(2) << toMB(MemPools::GetInstance().idleLimit()) << " MB\n";
/* limits */
- stream << "Total Pools created: " << mp_total.tot_pools_alloc << "\n";
- stream << "Pools ever used: " << mp_total.tot_pools_alloc - not_used << " (shown above)\n";
- stream << "Currently in use: " << mp_total.tot_pools_inuse << "\n";
+ auto poolCount = MemPools::GetInstance().pools.size();
+ stream << "Total Pools created: " << poolCount << "\n";
+ stream << "Pools ever used: " << poolCount - not_used << " (shown above)\n";
+ stream << "Currently in use: " << poolsInUse << "\n";
}
#include "cache_snmp.h"
#include "CachePeer.h"
#include "globals.h"
+#include "mem/Meter.h"
+#include "mem/Stats.h"
#include "mem_node.h"
#include "neighbors.h"
#include "snmp_agent.h"
SMI_COUNTER32);
break;
- case PERF_SYS_MEMUSAGE:
+ case PERF_SYS_MEMUSAGE: {
+ Mem::PoolStats stats;
+ Mem::GlobalStats(stats);
Answer = snmp_var_new_integer(Var->name, Var->name_length,
- (snint) statMemoryAccounted() >> 10,
+ (snint) stats.meter->alloc.currentLevel() >> 10,
ASN_INTEGER);
- break;
+ }
+ break;
case PERF_SYS_CPUTIME:
squid_getrusage(&rusage);
#include "HttpRequest.h"
#include "IoStats.h"
#include "mem/Pool.h"
+#include "mem/Stats.h"
#include "mem_node.h"
#include "MemBuf.h"
#include "MemObject.h"
#endif
- stats.total_accounted = statMemoryAccounted();
-
{
- MemPoolGlobalStats mp_stats;
- memPoolGetGlobalStats(&mp_stats);
- stats.gb_saved_count = mp_stats.TheMeter->gb_saved.count;
- stats.gb_freed_count = mp_stats.TheMeter->gb_freed.count;
+ Mem::PoolStats mp_stats;
+ Mem::GlobalStats(mp_stats);
+ stats.gb_saved_count = mp_stats.meter->gb_saved.count;
+ stats.gb_freed_count = mp_stats.meter->gb_freed.count;
+ stats.total_accounted = mp_stats.meter->alloc.currentLevel();
}
stats.max_fd = Squid_MaxFD;
storeAppendPrintf(sentry, "\tTotal accounted: %6.0f KB\n",
stats.total_accounted / 1024);
{
- MemPoolGlobalStats mp_stats;
- memPoolGetGlobalStats(&mp_stats);
+ Mem::PoolStats mp_stats;
+ Mem::GlobalStats(mp_stats); // XXX: called just for its side effects
storeAppendPrintf(sentry, "\tmemPoolAlloc calls: %9.0f\n",
stats.gb_saved_count);
storeAppendPrintf(sentry, "\tmemPoolFree calls: %9.0f\n",
#endif /* STAT_GRAPHS */
-int
-statMemoryAccounted(void)
-{
- return memPoolsTotalAllocated();
-}
-
void Mem::AllocatorProxy::freeOne(void *address) {xfree(address);}
int Mem::AllocatorProxy::inUseCount() const {return 0;}
//Mem::PoolMeter const &Mem::AllocatorProxy::getMeter() const STUB_RETSTATREF(PoolMeter)
-int Mem::AllocatorProxy::getStats(MemPoolStats *) STUB_RETVAL(0)
+size_t Mem::AllocatorProxy::getStats(PoolStats &) STUB_RETVAL(0)
#include "mem/forward.h"
void Mem::Init() STUB_NOP
void Mem::Stats(StoreEntry *) STUB_NOP
void Mem::CleanIdlePools(void *) STUB_NOP
void Mem::Report(std::ostream &) STUB_NOP
-void Mem::PoolReport(const MemPoolStats *, const PoolMeter *, std::ostream &) STUB_NOP
+void Mem::PoolReport(const PoolStats *, const PoolMeter *, std::ostream &) STUB_NOP
//const size_t squidSystemPageSize = 4096;
void memClean(void) STUB
void memInitModule(void) STUB
void MemPools::setDefaultPoolChunking(bool const &) STUB
//MemImplementingAllocator::MemImplementingAllocator(char const *, size_t) STUB_NOP
-//MemImplementingAllocator::~MemImplementingAllocator();
Mem::PoolMeter const &MemImplementingAllocator::getMeter() const STUB_RETSTATREF(PoolMeter)
Mem::PoolMeter &MemImplementingAllocator::getMeter() STUB_RETSTATREF(PoolMeter)
void MemImplementingAllocator::flushMetersFull() STUB
void MemImplementingAllocator::flushMeters() STUB
void *MemImplementingAllocator::alloc() STUB_RETVAL(nullptr)
void MemImplementingAllocator::freeOne(void *) STUB
+size_t MemImplementingAllocator::objectSize() const { return obj_size; }
-MemPoolIterator * memPoolIterate(void) STUB_RETVAL(nullptr)
-MemImplementingAllocator * memPoolIterateNext(MemPoolIterator *) STUB_RETVAL(nullptr)
-void memPoolIterateDone(MemPoolIterator **) STUB
-int memPoolGetGlobalStats(MemPoolGlobalStats *) STUB_RETVAL(0)
-int memPoolsTotalAllocated(void) STUB_RETVAL(0)
-
+#include "mem/Stats.h"
+size_t Mem::GlobalStats(PoolStats &) STUB_RETVAL(0)