From: Amos Jeffries Date: Thu, 27 Aug 2015 21:44:42 +0000 (-0700) Subject: SourceLayout: shuffle MemMeter into libmem and Mem:: namespace X-Git-Tag: SQUID_4_0_1~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9663db1c5b4d55566b19f220004aad2b0ee6c594;p=thirdparty%2Fsquid.git SourceLayout: shuffle MemMeter into libmem and Mem:: namespace * move the memMeter.h file to src/mem/Meter.h * move the helper #define macros logic to class members * provide accessors to make all class members private There are no logic changes in this patch. --- diff --git a/include/memMeter.h b/include/memMeter.h deleted file mode 100644 index 21fc09baa7..0000000000 --- a/include/memMeter.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 1996-2015 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 _MEM_METER_H_ -#define _MEM_METER_H_ - -/* object to track per-action memory usage (e.g. #idle objects) */ -class MemMeter -{ -public: - MemMeter() : level(0), hwater_level(0), hwater_stamp(0) {} - ssize_t level; /* current level (count or volume) */ - ssize_t hwater_level; /* high water mark */ - time_t hwater_stamp; /* timestamp of last high water mark change */ -}; - -#define memMeterSyncHWater(m) { (m).hwater_level = (m).level; (m).hwater_stamp = squid_curtime ? squid_curtime : time(NULL); } -#define memMeterCheckHWater(m) { if ((m).hwater_level < (m).level) memMeterSyncHWater((m)); } -#define memMeterInc(m) { (m).level++; memMeterCheckHWater(m); } -#define memMeterDec(m) { (m).level--; } -#define memMeterAdd(m, sz) { (m).level += (sz); memMeterCheckHWater(m); } -#define memMeterDel(m, sz) { (m).level -= (sz); } - -#endif /* _MEM_METER_H_ */ - diff --git a/src/cbdata.cc b/src/cbdata.cc index a24effd015..65955d88eb 100644 --- a/src/cbdata.cc +++ b/src/cbdata.cc @@ -500,7 +500,7 @@ cbdataDump(StoreEntry * sentry) #else int obj_size = pool->objectSize() - cbdata::Offset; #endif - storeAppendPrintf(sentry, "%s\t%d\t%ld\t%ld\n", pool->objectType() + 7, obj_size, (long int)pool->getMeter().inuse.level, (long int)obj_size * pool->getMeter().inuse.level); + storeAppendPrintf(sentry, "%s\t%d\t%ld\t%ld\n", pool->objectType() + 7, obj_size, (long int)pool->getMeter().inuse.currentLevel(), (long int)obj_size * pool->getMeter().inuse.currentLevel()); } } diff --git a/src/mem/Makefile.am b/src/mem/Makefile.am index eeb3135280..74fae3ec3c 100644 --- a/src/mem/Makefile.am +++ b/src/mem/Makefile.am @@ -15,6 +15,7 @@ libmem_la_SOURCES = \ AllocatorProxy.h \ forward.h \ old_api.cc \ + Meter.h \ Pool.cc \ Pool.h \ PoolChunked.cc \ diff --git a/src/mem/Meter.h b/src/mem/Meter.h new file mode 100644 index 0000000000..b0d66e8809 --- /dev/null +++ b/src/mem/Meter.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 1996-2015 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_METER_H +#define SQUID_SRC_MEM_METER_H + +#include "SquidTime.h" + +namespace Mem +{ + +/** + * object to track per-action memory usage (e.g. #idle objects) + */ +class Meter +{ +public: + Meter() : level(0), hwater_level(0), hwater_stamp(0) {} + + /// flush the meter level back to 0, but leave peak records + void flush() {level=0;} + + ssize_t currentLevel() const {return level;} + ssize_t peak() const {return hwater_level;} + time_t peakTime() const {return hwater_stamp;} + + Meter &operator ++() {++level; checkHighWater(); return *this;} + Meter &operator --() {--level; return *this;} + + Meter &operator +=(ssize_t n) { level += n; checkHighWater(); return *this;} + Meter &operator -=(ssize_t n) { level -= n; return *this;} + +private: + /// check the high-water level of this meter and raise if necessary + /// recording the timestamp of last high-water peak change + void checkHighWater() { + if (hwater_level < level) { + hwater_level = level; + hwater_stamp = squid_curtime ? squid_curtime : time(NULL); + } + } + + ssize_t level; ///< current level (count or volume) + ssize_t hwater_level; ///< high water mark + time_t hwater_stamp; ///< timestamp of last high water mark change +}; + +} // namespace Mem + +#endif /* SQUID_SRC_MEM_METER_H */ + diff --git a/src/mem/Pool.cc b/src/mem/Pool.cc index ed887e5203..9e3e4865fa 100644 --- a/src/mem/Pool.cc +++ b/src/mem/Pool.cc @@ -154,9 +154,9 @@ MemImplementingAllocator::flushMetersFull() void MemPoolMeter::flush() { - alloc.level = 0; - inuse.level = 0; - idle.level = 0; + alloc.flush(); + inuse.flush(); + idle.flush(); gb_allocated.count = 0; gb_allocated.bytes = 0; gb_oallocated.count = 0; @@ -178,17 +178,16 @@ MemPoolMeter::MemPoolMeter() void MemPools::flushMeters() { - MemImplementingAllocator *pool; - MemPoolIterator *iter; - TheMeter.flush(); - iter = memPoolIterate(); - while ((pool = memPoolIterateNext(iter))) { + MemPoolIterator *iter = memPoolIterate(); + while (MemImplementingAllocator *pool = memPoolIterateNext(iter)) { pool->flushMetersFull(); - 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); + // are these TheMeter grow() operations or accumulated volumes ? + TheMeter.alloc += pool->getMeter().alloc.currentLevel() * pool->obj_size; + TheMeter.inuse += pool->getMeter().inuse.currentLevel() * pool->obj_size; + TheMeter.idle += pool->getMeter().idle.currentLevel() * 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; @@ -234,7 +233,7 @@ MemPools::clean(time_t maxage) return; int shift = 1; - if (TheMeter.idle.level > mem_idle_limit) + if (TheMeter.idle.currentLevel() > mem_idle_limit) maxage = shift = 0; MemImplementingAllocator *pool; @@ -312,7 +311,7 @@ memPoolsTotalAllocated(void) { MemPoolGlobalStats stats; memPoolGetGlobalStats(&stats); - return stats.TheMeter->alloc.level; + return stats.TheMeter->alloc.currentLevel(); } MemImplementingAllocator::MemImplementingAllocator(char const *aLabel, size_t aSize) : MemAllocator(aLabel), diff --git a/src/mem/Pool.h b/src/mem/Pool.h index 550edc28ab..5face24628 100644 --- a/src/mem/Pool.h +++ b/src/mem/Pool.h @@ -28,7 +28,7 @@ * might be the way to go. */ -#include "memMeter.h" +#include "mem/Meter.h" #include "splay.h" #include "util.h" @@ -95,9 +95,10 @@ class MemPoolMeter public: MemPoolMeter(); void flush(); - MemMeter alloc; - MemMeter inuse; - MemMeter idle; + + Mem::Meter alloc; + Mem::Meter inuse; + Mem::Meter idle; /** history Allocations */ mgb_t gb_allocated; diff --git a/src/mem/PoolChunked.cc b/src/mem/PoolChunked.cc index b630c227fc..88138bcd18 100644 --- a/src/mem/PoolChunked.cc +++ b/src/mem/PoolChunked.cc @@ -128,8 +128,8 @@ MemChunk::MemChunk(MemPoolChunked *aPool) nextFreeChunk = pool->nextFreeChunk; pool->nextFreeChunk = this; - memMeterAdd(pool->getMeter().alloc, pool->chunk_capacity); - memMeterAdd(pool->getMeter().idle, pool->chunk_capacity); + pool->getMeter().alloc += pool->chunk_capacity; + pool->getMeter().idle += pool->chunk_capacity; ++pool->chunkCount; lastref = squid_curtime; pool->allChunks.insert(this, memCompChunks); @@ -149,8 +149,8 @@ MemPoolChunked::MemPoolChunked(const char *aLabel, size_t aSize) : MemChunk::~MemChunk() { - memMeterDel(pool->getMeter().alloc, pool->chunk_capacity); - memMeterDel(pool->getMeter().idle, pool->chunk_capacity); + pool->getMeter().alloc -= pool->chunk_capacity; + pool->getMeter().idle -= pool->chunk_capacity; -- pool->chunkCount; pool->allChunks.remove(this, memCompChunks); xfree(objCache); @@ -288,7 +288,7 @@ MemPoolChunked::~MemPoolChunked() flushMetersFull(); clean(0); - assert(meter.inuse.level == 0); + assert(meter.inuse.currentLevel() == 0); chunk = Chunks; while ( (fchunk = chunk) != NULL) { @@ -302,16 +302,16 @@ MemPoolChunked::~MemPoolChunked() int MemPoolChunked::getInUseCount() { - return meter.inuse.level; + return meter.inuse.currentLevel(); } void * MemPoolChunked::allocate() { void *p = get(); - assert(meter.idle.level > 0); - memMeterDec(meter.idle); - memMeterInc(meter.inuse); + assert(meter.idle.currentLevel() > 0); + --meter.idle; + ++meter.inuse; return p; } @@ -319,9 +319,9 @@ void MemPoolChunked::deallocate(void *obj, bool) { push(obj); - assert(meter.inuse.level > 0); - memMeterDec(meter.inuse); - memMeterInc(meter.idle); + assert(meter.inuse.currentLevel() > 0); + --meter.inuse; + ++meter.idle; } void @@ -417,7 +417,7 @@ MemPoolChunked::clean(time_t maxage) bool MemPoolChunked::idleTrigger(int shift) const { - return meter.idle.level > (chunk_capacity << shift); + return meter.idle.currentLevel() > (chunk_capacity << shift); } /* @@ -456,12 +456,12 @@ MemPoolChunked::getStats(MemPoolStats * stats, int accumulate) stats->chunks_partial += chunks_partial; stats->chunks_free += chunks_free; - stats->items_alloc += meter.alloc.level; - stats->items_inuse += meter.inuse.level; - stats->items_idle += meter.idle.level; + 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; - return meter.inuse.level; + return meter.inuse.currentLevel(); } diff --git a/src/mem/PoolMalloc.cc b/src/mem/PoolMalloc.cc index 025aa41a77..39cc997ca9 100644 --- a/src/mem/PoolMalloc.cc +++ b/src/mem/PoolMalloc.cc @@ -28,30 +28,30 @@ MemPoolMalloc::allocate() freelist.pop(); } if (obj) { - memMeterDec(meter.idle); + --meter.idle; ++saved_calls; } else { if (doZero) obj = xcalloc(1, obj_size); else obj = xmalloc(obj_size); - memMeterInc(meter.alloc); + ++meter.alloc; } - memMeterInc(meter.inuse); + ++meter.inuse; return obj; } void MemPoolMalloc::deallocate(void *obj, bool aggressive) { - memMeterDec(meter.inuse); + --meter.inuse; if (aggressive) { xfree(obj); - memMeterDec(meter.alloc); + --meter.alloc; } else { if (doZero) memset(obj, 0, obj_size); - memMeterInc(meter.idle); + ++meter.idle; freelist.push(obj); } } @@ -74,19 +74,19 @@ MemPoolMalloc::getStats(MemPoolStats * stats, int accumulate) stats->chunks_partial += 0; stats->chunks_free += 0; - stats->items_alloc += meter.alloc.level; - stats->items_inuse += meter.inuse.level; - stats->items_idle += meter.idle.level; + 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.level; + return meter.inuse.currentLevel(); } int MemPoolMalloc::getInUseCount() { - return meter.inuse.level; + return meter.inuse.currentLevel(); } MemPoolMalloc::MemPoolMalloc(char const *aLabel, size_t aSize) : MemImplementingAllocator(aLabel, aSize) @@ -95,7 +95,7 @@ MemPoolMalloc::MemPoolMalloc(char const *aLabel, size_t aSize) : MemImplementing MemPoolMalloc::~MemPoolMalloc() { - assert(meter.inuse.level == 0); + assert(meter.inuse.currentLevel() == 0); clean(0); } @@ -111,8 +111,8 @@ MemPoolMalloc::clean(time_t) while (!freelist.empty()) { void *obj = freelist.top(); freelist.pop(); - memMeterDec(meter.idle); - memMeterDec(meter.alloc); + --meter.idle; + --meter.alloc; xfree(obj); } } diff --git a/src/mem/forward.h b/src/mem/forward.h index f87b789030..c7d262e867 100644 --- a/src/mem/forward.h +++ b/src/mem/forward.h @@ -21,6 +21,7 @@ class StoreEntry; class MemPoolStats; class MemPoolMeter; +/// Memory Management namespace Mem { void Init(); diff --git a/src/mem/old_api.cc b/src/mem/old_api.cc index b01a2f3138..cba5a0a611 100644 --- a/src/mem/old_api.cc +++ b/src/mem/old_api.cc @@ -19,9 +19,9 @@ #include "icmp/net_db.h" #include "md5.h" #include "mem/forward.h" +#include "mem/Meter.h" #include "mem/Pool.h" #include "MemBuf.h" -#include "memMeter.h" #include "mgr/Registration.h" #include "SquidConfig.h" #include "SquidList.h" @@ -94,11 +94,11 @@ static struct { } StrPools[mem_str_pool_count]; -static MemMeter StrCountMeter; -static MemMeter StrVolumeMeter; +static Mem::Meter StrCountMeter; +static Mem::Meter StrVolumeMeter; -static MemMeter HugeBufCountMeter; -static MemMeter HugeBufVolumeMeter; +static Mem::Meter HugeBufCountMeter; +static Mem::Meter HugeBufVolumeMeter; /* local routines */ @@ -114,30 +114,27 @@ memStringStats(std::ostream &stream) for (i = 0; i < mem_str_pool_count; ++i) { const MemAllocator *pool = StrPools[i].pool; - const int plevel = pool->getMeter().inuse.level; + const auto plevel = pool->getMeter().inuse.currentLevel(); stream << std::setw(20) << std::left << pool->objectType(); - stream << std::right << "\t " << xpercentInt(plevel, StrCountMeter.level); - stream << "\t " << xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.level) << "\n"; + stream << std::right << "\t " << xpercentInt(plevel, StrCountMeter.currentLevel()); + stream << "\t " << xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.currentLevel()) << "\n"; pooled_count += plevel; pooled_volume += plevel * pool->objectSize(); } /* malloc strings */ stream << std::setw(20) << std::left << "Other Strings"; - stream << std::right << "\t "; - - stream << xpercentInt(StrCountMeter.level - pooled_count, StrCountMeter.level) << "\t "; - - stream << xpercentInt(StrVolumeMeter.level - pooled_volume, StrVolumeMeter.level) << "\n\n"; + stream << xpercentInt(StrCountMeter.currentLevel() - pooled_count, StrCountMeter.currentLevel()) << "\t "; + stream << xpercentInt(StrVolumeMeter.currentLevel() - pooled_volume, StrVolumeMeter.currentLevel()) << "\n\n"; } static void memBufStats(std::ostream & stream) { stream << "Large buffers: " << - HugeBufCountMeter.level << " (" << - HugeBufVolumeMeter.level / 1024 << " KB)\n"; + HugeBufCountMeter.currentLevel() << " (" << + HugeBufVolumeMeter.currentLevel() / 1024 << " KB)\n"; } void @@ -227,8 +224,8 @@ memAllocString(size_t net_size, size_t * gross_size) *gross_size = pool ? StrPoolsAttrs[i].obj_size : net_size; assert(*gross_size >= net_size); // may forget [de]allocations until MemIsInitialized - memMeterInc(StrCountMeter); - memMeterAdd(StrVolumeMeter, *gross_size); + ++StrCountMeter; + StrVolumeMeter += *gross_size; return pool ? pool->alloc() : xcalloc(1, net_size); } @@ -261,8 +258,8 @@ memFreeString(size_t size, void *buf) } // may forget [de]allocations until MemIsInitialized - memMeterDec(StrCountMeter); - memMeterDel(StrVolumeMeter, size); + --StrCountMeter; + StrVolumeMeter -= size; pool ? pool->freeOne(buf) : xfree(buf); } @@ -311,8 +308,8 @@ memAllocBuf(size_t net_size, size_t * gross_size) if (type != MEM_NONE) return memAllocate(type); else { - memMeterInc(HugeBufCountMeter); - memMeterAdd(HugeBufVolumeMeter, *gross_size); + ++HugeBufCountMeter; + HugeBufVolumeMeter += *gross_size; return xcalloc(1, net_size); } } @@ -351,8 +348,8 @@ memFreeBuf(size_t size, void *buf) memFree(buf, type); else { xfree(buf); - memMeterDec(HugeBufCountMeter); - memMeterDel(HugeBufVolumeMeter, size); + --HugeBufCountMeter; + HugeBufVolumeMeter -= size; } } @@ -586,8 +583,8 @@ memFreeBufFunc(size_t size) return memFree64K; default: - memMeterDec(HugeBufCountMeter); - memMeterDel(HugeBufVolumeMeter, size); + --HugeBufCountMeter; + HugeBufVolumeMeter -= size; return cxx_xfree; } } @@ -634,7 +631,7 @@ Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std:: } /* * Fragmentation calculation: - * needed = inuse.level / chunk_capacity + * needed = inuse.currentLevel() / chunk_capacity * excess = used - needed * fragmentation = excess / needed * 100% * @@ -642,20 +639,20 @@ Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std:: */ /* allocated */ stream << mp_st->items_alloc << delim; - stream << toKB(mp_st->obj_size * pm->alloc.level) << delim; - stream << toKB(mp_st->obj_size * pm->alloc.hwater_level) << delim; - stream << std::setprecision(2) << ((squid_curtime - pm->alloc.hwater_stamp) / 3600.) << delim; - stream << std::setprecision(3) << xpercent(mp_st->obj_size * pm->alloc.level, AllMeter->alloc.level) << delim; + stream << toKB(mp_st->obj_size * pm->alloc.currentLevel()) << delim; + stream << toKB(mp_st->obj_size * pm->alloc.peak()) << delim; + stream << std::setprecision(2) << ((squid_curtime - pm->alloc.peakTime()) / 3600.) << delim; + stream << std::setprecision(3) << xpercent(mp_st->obj_size * pm->alloc.currentLevel(), AllMeter->alloc.currentLevel()) << delim; /* in use */ stream << mp_st->items_inuse << delim; - stream << toKB(mp_st->obj_size * pm->inuse.level) << delim; - stream << toKB(mp_st->obj_size * pm->inuse.hwater_level) << delim; - stream << std::setprecision(2) << ((squid_curtime - pm->inuse.hwater_stamp) / 3600.) << delim; - stream << std::setprecision(3) << xpercent(pm->inuse.level, pm->alloc.level) << delim; + stream << toKB(mp_st->obj_size * pm->inuse.currentLevel()) << delim; + stream << toKB(mp_st->obj_size * pm->inuse.peak()) << delim; + stream << std::setprecision(2) << ((squid_curtime - pm->inuse.peakTime()) / 3600.) << delim; + stream << std::setprecision(3) << xpercent(pm->inuse.currentLevel(), pm->alloc.currentLevel()) << delim; /* idle */ stream << mp_st->items_idle << delim; - stream << toKB(mp_st->obj_size * pm->idle.level) << delim; - stream << toKB(mp_st->obj_size * pm->idle.hwater_level) << delim; + stream << toKB(mp_st->obj_size * pm->idle.currentLevel()) << delim; + stream << toKB(mp_st->obj_size * pm->idle.peak()) << delim; /* saved */ stream << (int)pm->gb_saved.count << delim; stream << std::setprecision(3) << xpercent(pm->gb_saved.count, AllMeter->gb_allocated.count) << delim; @@ -672,8 +669,8 @@ MemPoolReportSorter(const void *a, const void *b) // use this to sort on %Total Allocated // - double pa = (double) A->obj_size * A->meter->alloc.level; - double pb = (double) B->obj_size * B->meter->alloc.level; + 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; @@ -684,10 +681,10 @@ MemPoolReportSorter(const void *a, const void *b) #if 0 // use this to sort on In Use high(hrs) // - if (A->meter->inuse.hwater_stamp > B->meter->inuse.hwater_stamp) + if (A->meter->inuse.peakTime() > B->meter->inuse.peakTime()) return -1; - if (B->meter->inuse.hwater_stamp > A->meter->inuse.hwater_stamp) + if (B->meter->inuse.peakTime() > A->meter->inuse.peakTime()) return 1; #endif @@ -783,7 +780,7 @@ Mem::Report(std::ostream &stream) 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"; + std::setprecision(3) << xpercent(mp_total.tot_overhead, mp_total.TheMeter->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";