--------------------- PatchSet 2194 Date: 2001/05/03 14:31:39 Author: akroonmaa Branch: chunked_mempools Tag: (none) Log: undo command function. API calls now defined as before move memPool maintenance funcs away from MemPoolStats.c to mem.c leave library with minimal required funcs. add statistics call to API - perpool and totals share NO data structures with lib Members: include/MemPool.h:1.1.2.12->1.1.2.13 lib/MemPool.c:1.1.2.14->1.1.2.15 src/MemPoolStats.c:1.1.2.17->1.1.2.18 src/mem.c:1.9.8.5->1.9.8.6 src/protos.h:1.23.4.7->1.23.4.8 src/stat.c:1.9.8.4->1.9.8.5 Index: squid/include/MemPool.h =================================================================== RCS file: /cvsroot/squid-sf//squid/include/Attic/MemPool.h,v retrieving revision 1.1.2.12 retrieving revision 1.1.2.13 diff -u -r1.1.2.12 -r1.1.2.13 --- squid/include/MemPool.h 2 May 2001 20:21:59 -0000 1.1.2.12 +++ squid/include/MemPool.h 3 May 2001 14:31:39 -0000 1.1.2.13 @@ -12,6 +12,9 @@ #endif #define MB ((size_t)1024*1024) +#define mem_unlimited_size 2 * 1024 * MB +#define toMB(size) ( ((double) size) / MB ) +#define toKB(size) ( (size + 1024 - 1) / 1024 ) #define MEM_PAGE_SIZE 4096 #define MEM_CHUNK_SIZE 4096 * 4 @@ -19,30 +22,12 @@ #define MEM_MIN_FREE 32 #define MEM_MAX_FREE 65535 /* ushort is max number of items per chunk */ -enum { - MPOOL_INIT, - MPOOL_TUNE_CHUNKSIZE, - MPOOL_FLUSH_METERS, - MPOOL_CLEAN_POOL, - MPOOL_GET_INUSE, - MPOOL_SYNC_HWATER, - MPOOL_DESTROY, - MPOOL_GET_IDLE_LIMIT, - MPOOL_SET_IDLE_LIMIT, - MPOOL_GET_TOTAL, - MPOOL_GET_THEMETER, - MPOOL_GET_STATS, - MPOOL_CLEAN_MODULE, - MPOOL_GET_OVERHEAD -}; - typedef struct _MemPoolMeter MemPoolMeter; typedef struct _MemPool MemPool; typedef struct _MemMeter MemMeter; typedef struct _MemChunk MemChunk; typedef struct _MemPoolStats MemPoolStats; - /* object to track per-action memory usage (e.g. #idle objects) */ struct _MemMeter { ssize_t level; /* current level (count or volume) */ @@ -61,8 +46,9 @@ MemMeter alloc; MemMeter inuse; MemMeter idle; - mgb_t gb_saved; - mgb_t gb_osaved; + mgb_t gb_saved; /* account Allocations */ + mgb_t gb_osaved; /* history Allocations */ + mgb_t gb_freed; /* account Free calls */ }; /* a pool is a [growing] space for objects of the same size */ @@ -108,45 +94,35 @@ int items_inuse; int items_idle; int overhead; + int mem_idle_limit; }; #define SIZEOF_CHUNK ( ( sizeof(MemChunk) + sizeof(double) -1) / sizeof(double) ) * sizeof(double); -extern unsigned int mem_pool_alloc_calls; -extern unsigned int mem_pool_free_calls; - /* memPools */ -extern void memConfigure(void); -extern void memInitModule(void); - -extern int memPoolControl(void ** pool, int cmd, size_t value); +/* Public user API */ extern MemPool *memPoolCreate(const char *label, size_t obj_size); +extern void memPoolTune(MemPool * pool, size_t chunksize, int unused); extern void *memPoolAlloc(MemPool * pool); extern void memPoolFree(MemPool * pool, void *obj); -extern void memPoolCleanIdlePools(void *unused); - -#if !MPOOL_INTERNAL -#define memPoolTune(pool, size, un) ( memPoolControl((void *) (pool), MPOOL_TUNE_CHUNKSIZE, (size)) ) -#define memPoolInUseCount(pool) ( memPoolControl((void *) (pool), MPOOL_GET_INUSE, 0) ) -#define memPoolFlushMeters(pool) ( memPoolControl((void *) (pool), MPOOL_FLUSH_METERS, 0) ) -#define memPoolDestroy(pool) ( memPoolControl((void *) (pool), MPOOL_DESTROY, 0) ) -#define memPoolClean(pool, maxage) ( memPoolControl((void *) (pool), MPOOL_CLEAN_POOL, (maxage)) ) -#define memPoolCleanModule() ( memPoolControl(0, MPOOL_CLEAN_MODULE, 0) ) -#define memPoolInit() ( memPoolControl(0, MPOOL_INIT, 0) ) -#define memPoolIdleLimit() ( memPoolControl(0, MPOOL_GET_IDLE_LIMIT, 0) ) -#define memPoolSetIdleLimit(limit) ( memPoolControl(0, MPOOL_SET_IDLE_LIMIT, (limit)) ) -#define memPoolsTotalAllocated() ( memPoolControl(0, MPOOL_GET_TOTAL, 0) ) -#define memPoolGetOverhead() ( memPoolControl(0, MPOOL_GET_OVERHEAD, 0) ) -#define memPoolGetStats(stats, i) ( memPoolControl((void *) (stats), MPOOL_GET_STATS, (i)) ) -#define memPoolGetTheMeter(meter) ( memPoolControl((void *) (meter), MPOOL_GET_THEMETER, 0) ) +extern void memPoolDestroy(MemPool * pool); +extern int memPoolGetStats(MemPoolStats * stats, MemPool * pool, int index); -#define memMeterSyncHWater(meter) ( memPoolControl((void *) (meter), MPOOL_SYNC_HWATER, 0) ) -#endif +/* Module housekeeping API */ +extern void memPoolInit(void); +extern void memPoolClean(MemPool * pool, time_t maxage, int new_idle_limit); +/* Wrappers under src/mem.c */ +extern void memConfigure(void); +extern void memPoolCleanIdlePools(void *unused); +extern int memPoolInUseCount(MemPool * pool); +extern int memPoolsTotalAllocated(void); /* MemMeter */ +extern void memMeterSyncHWater(MemMeter * m); + #define memMeterCheckHWater(m) { if ((m).hwater_level < (m).level) memMeterSyncHWater(&(m)); } #define memMeterInc(m) { (m).level++; memMeterCheckHWater(m); } #define memMeterDec(m) { (m).level--; } Index: squid/lib/MemPool.c =================================================================== RCS file: /cvsroot/squid-sf//squid/lib/Attic/MemPool.c,v retrieving revision 1.1.2.14 retrieving revision 1.1.2.15 diff -u -r1.1.2.14 -r1.1.2.15 --- squid/lib/MemPool.c 2 May 2001 20:21:59 -0000 1.1.2.14 +++ squid/lib/MemPool.c 3 May 2001 14:31:39 -0000 1.1.2.15 @@ -81,54 +81,55 @@ */ #define FLUSH_LIMIT 1000 /* Flush memPool counters to memMeters after flush limit calls */ -#define MPOOL_INTERNAL 1 + #include -#include #include "config.h" #include "Stack.h" #include "MemPool.h" -/* XXX This is a boundary violation between lib and src.. would be good +/* + * XXX This is a boundary violation between lib and src.. would be good * if it could be solved otherwise, but left for now. */ extern time_t squid_curtime; -/* exported */ -unsigned int mem_pool_alloc_calls = 0; -unsigned int mem_pool_free_calls = 0; - -int memPoolControl(void **pool, int cmd, size_t value); +/* Public user API */ MemPool *memPoolCreate(const char *label, size_t obj_size); +void memPoolTune(MemPool * pool, size_t chunksize, int unused); void *memPoolAlloc(MemPool * pool); void memPoolFree(MemPool * pool, void *obj); +void memPoolDestroy(MemPool * pool); +int memPoolGetStats(MemPoolStats * stats, MemPool * pool, int index); -/* locals */ -static MemPoolMeter TheMeter; -static size_t mem_idle_limit = 0; +/* Module housekeeping */ +void memPoolInit(void); +void memPoolClean(MemPool * pool, time_t maxage, int new_idle_limit); + +/* Helpers */ +void memMeterSyncHWater(MemMeter * m); +/* local data */ +static int mem_idle_limit = 0; static Array PoolArray; +static MemPoolMeter TheMeter; + static int Pool_id_counter = 0; static int bounds; static MemPool *lastPool; -static int memPoolCleanModule(void); -static void memMeterSyncHWater(MemMeter * m); +/* local prototypes */ static int memCompChunks(MemChunk * chunkA, MemChunk * chunkB); static int memCompObjChunks(void *obj, MemChunk * chunk); -static MemChunk *memPoolChunkNew(MemPool * pool); +static MemChunk * memPoolChunkNew(MemPool * pool); static void memPoolChunkDestroy(MemPool * pool, MemChunk * chunk); static void memPoolPush(MemPool * pool, void *obj); -static void *memPoolGet(MemPool * pool); +static void * memPoolGet(MemPool * pool); static void memPoolCreateChunk(MemPool * pool); -static void memPoolTune(MemPool * pool, size_t chunksize, int unused); -static void memPoolDestroy(MemPool * pool); +static void memPoolFlushMetersOne(MemPool * pool); static void memPoolFlushMeters(MemPool * pool); static void memPoolCleanOne(MemPool * pool, time_t maxage); -static void memPoolClean(MemPool * onePool, time_t maxage); -static void memPoolFlushMetersAll(MemPool * onePool); -static int memPoolInUseCount(const MemPool * pool); -static int memPoolGetStats(MemPoolStats * mp_st, int index); +static void memPoolGetStatsOne(MemPoolStats * stats, MemPool * pool); static void memArrayInit(Array * a); #if UNUSED_CODE @@ -138,7 +139,7 @@ static void memArrayAppend(Array * s, void *obj); static void memArrayGrow(Array * a, int min_capacity); -static void +void memMeterSyncHWater(MemMeter * m) { assert(m); @@ -148,12 +149,14 @@ } } +/* Compare chunks */ static int memCompChunks(MemChunk * chunkA, MemChunk * chunkB) { return chunkA->objCache - chunkB->objCache; } +/* Compare object to chunk */ static int memCompObjChunks(void *obj, MemChunk * chunk) { @@ -291,63 +294,15 @@ return; } -int -memPoolControl(void **pool, int cmd, size_t value) +void +memPoolInit(void) { - int ret = 0; - switch (cmd) { - case MPOOL_TUNE_CHUNKSIZE: - memPoolTune((MemPool *) pool, value, 0); - break; - case MPOOL_FLUSH_METERS: - memPoolFlushMetersAll((MemPool *) pool); - break; - case MPOOL_CLEAN_POOL: - memPoolClean((MemPool *) pool, value); - break; - case MPOOL_INIT: - memArrayInit(&PoolArray); - memset(&TheMeter, 0, sizeof(TheMeter)); - break; - case MPOOL_GET_INUSE: - ret = memPoolInUseCount((MemPool *) pool); - break; - case MPOOL_DESTROY: - memPoolDestroy((MemPool *) pool); - break; - case MPOOL_SYNC_HWATER: - memMeterSyncHWater((MemMeter *) pool); - break; - case MPOOL_GET_THEMETER: - *pool = &TheMeter; - break; - case MPOOL_GET_IDLE_LIMIT: - ret = mem_idle_limit; - break; - case MPOOL_SET_IDLE_LIMIT: - ret = mem_idle_limit - value; - mem_idle_limit = value; - break; - case MPOOL_GET_STATS: - ret = memPoolGetStats((MemPoolStats *) pool, value); - break; - case MPOOL_GET_TOTAL: - memPoolFlushMeters(NULL); - ret = TheMeter.alloc.level; - break; - case MPOOL_CLEAN_MODULE: - ret = memPoolCleanModule(); - break; - case MPOOL_GET_OVERHEAD: - ret = sizeof(Array) + PoolArray.capacity * sizeof(MemPool *); - break; - default: - ret = -1; - } - return ret; + memArrayInit(&PoolArray); + memset(&TheMeter, 0, sizeof(TheMeter)); + mem_idle_limit = 0; } -static void +void memPoolTune(MemPool * pool, size_t chunksize, int unused) { int cap; @@ -395,22 +350,20 @@ * warning: we do not clean this entry from Pools assuming memPoolDestroy * is used at the end of the program only */ -static void +void memPoolDestroy(MemPool * pool) { assert(pool); } static void -memPoolFlushMeters(MemPool * pool) +memPoolFlushMetersOne(MemPool * pool) { size_t calls; - size_t bytes; calls = pool->free_calls; if (calls) { - bytes = pool->obj_size * pool->free_calls; - mem_pool_free_calls += calls; + pool->meter.gb_freed.count += calls; memMeterDel(pool->meter.inuse, calls); #if !DISABLE_POOLS memMeterAdd(pool->meter.idle, calls); @@ -419,12 +372,8 @@ } calls = pool->alloc_calls; if (calls) { - bytes = pool->obj_size * pool->alloc_calls; - - memMeterAdd(pool->meter.inuse, calls); pool->meter.gb_saved.count += calls; - mem_pool_alloc_calls += calls; - + memMeterAdd(pool->meter.inuse, calls); #if !DISABLE_POOLS memMeterDel(pool->meter.idle, calls); #endif @@ -432,6 +381,43 @@ } } +/* + * Updates all pool counters, and recreates TheMeter totals from all pools + */ +static void +memPoolFlushMeters(MemPool * pool) +{ + int i; + MemPool *onePool; + if (pool) { + memPoolFlushMetersOne(pool); + pool->meter.gb_saved.bytes = pool->meter.gb_saved.count * pool->obj_size; + pool->meter.gb_freed.bytes = pool->meter.gb_freed.count * pool->obj_size; + return; + } + + TheMeter.alloc.level = 0; + TheMeter.inuse.level = 0; + TheMeter.idle.level = 0; + TheMeter.gb_saved.count = 0; + TheMeter.gb_saved.bytes = 0; + TheMeter.gb_freed.count = 0; + TheMeter.gb_freed.bytes = 0; + for (i = 0; i < PoolArray.count; i++) { + onePool = PoolArray.items[i]; + memPoolFlushMetersOne(onePool); + memMeterAdd(TheMeter.alloc, onePool->meter.alloc.level * onePool->obj_size); + memMeterAdd(TheMeter.inuse, onePool->meter.inuse.level * onePool->obj_size); + memMeterAdd(TheMeter.idle, onePool->meter.idle.level * onePool->obj_size); + TheMeter.gb_saved.count += onePool->meter.gb_saved.count; + TheMeter.gb_freed.count += onePool->meter.gb_freed.count; + TheMeter.gb_saved.bytes += onePool->meter.gb_saved.count * onePool->obj_size; + TheMeter.gb_freed.bytes += onePool->meter.gb_freed.count * onePool->obj_size; + onePool->meter.gb_saved.bytes = onePool->meter.gb_saved.count * onePool->obj_size; + onePool->meter.gb_freed.bytes = onePool->meter.gb_freed.count * onePool->obj_size; + } +} + void * memPoolAlloc(MemPool * pool) { @@ -448,7 +434,7 @@ p = xcalloc(1, pool->obj_size); #endif if (++pool->alloc_calls == FLUSH_LIMIT) - memPoolFlushMeters(pool); + memPoolFlushMetersOne(pool); return p; } @@ -557,117 +543,115 @@ return; } -static void -memPoolClean(MemPool * onePool, time_t maxage) +/* + * Returns all cached frees to their home chunks + * If chunks unreferenced age is over, destroys Idle chunk + * Flushes meters for a pool + * If pool is not specified, iterates through all pools. + * When used for all pools, if new_idle_limit is above -1, new + * idle memory limit is set before Cleanup. This allows to shrink + * memPool memory usage to specified minimum. + */ +void +memPoolClean(MemPool * pool, time_t maxage, int new_idle_limit) { int i; - MemPool *pool; + MemPool *onePool; int shift = 1; - if (onePool) - return memPoolCleanOne(onePool, maxage); - - memPoolFlushMetersAll(NULL); + if (pool) { + memPoolFlushMetersOne(pool); + memPoolCleanOne(pool, maxage); + return; + } + if (new_idle_limit >= 0) + mem_idle_limit = new_idle_limit; + memPoolFlushMeters(NULL); if (TheMeter.idle.level > mem_idle_limit) maxage = shift = 0; for (i = 0; i < PoolArray.count; i++) { - pool = PoolArray.items[i]; - if (pool->meter.idle.level > (pool->chunk_capacity << shift)) { - memPoolCleanOne(pool, maxage); + onePool = PoolArray.items[i]; + if (onePool->meter.idle.level > (onePool->chunk_capacity << shift)) { + memPoolCleanOne(onePool, maxage); } } } -/* updates all pool counters, and recreates TheMeter totals from all pools */ +/* + * Update MemPoolStats struct for single pool + */ static void -memPoolFlushMetersAll(MemPool * onePool) +memPoolGetStatsOne(MemPoolStats * stats, MemPool * pool) { - int i; - MemPool *pool; - if (onePool) - return memPoolFlushMeters(onePool); - - TheMeter.alloc.level = 0; - TheMeter.inuse.level = 0; - TheMeter.idle.level = 0; - TheMeter.gb_saved.count = 0; - TheMeter.gb_saved.bytes = 0; - for (i = 0; i < PoolArray.count; i++) { - pool = PoolArray.items[i]; - memPoolFlushMeters(pool); - memMeterAdd(TheMeter.alloc, pool->meter.alloc.level * pool->obj_size); - memMeterAdd(TheMeter.inuse, pool->meter.inuse.level * pool->obj_size); - memMeterAdd(TheMeter.idle, pool->meter.idle.level * pool->obj_size); - TheMeter.gb_saved.count += pool->meter.gb_saved.count; - TheMeter.gb_saved.bytes += pool->meter.gb_saved.count * pool->obj_size; - pool->meter.gb_saved.bytes = pool->meter.gb_saved.count * pool->obj_size; - } -} - -static int -memPoolCleanModule(void) -{ - int i; - int dirty_count = 0; - for (i = 0; i < PoolArray.count; i++) { - MemPool *pool = PoolArray.items[i]; - if (memPoolInUseCount(pool)) { - dirty_count++; - } else { - memPoolDestroy(pool); - } - } - return dirty_count; -} - -static int -memPoolGetStats(MemPoolStats * mp_st, int index) -{ - MemPool *pool; MemChunk *chunk; - if (index < 0) - return -1; - if (index > PoolArray.count) - return -2; - if (index == PoolArray.count) - return 0; - pool = PoolArray.items[index]; - mp_st->pool = pool; - if (!pool) - return index + 1; - memPoolClean(pool, (time_t) 555555); /* don't want to get chunks released before reporting */ - mp_st->label = pool->label; - mp_st->meter = &pool->meter; - mp_st->obj_size = pool->obj_size; - mp_st->chunk_capacity = pool->chunk_capacity; - - mp_st->chunks_alloc = pool->chunkCount; - mp_st->chunks_partial = 0; - mp_st->chunks_free = 0; - mp_st->overhead = sizeof(MemPool) + sizeof(MemPool *) + pool->chunkCount * sizeof(MemChunk); + int chunks_free = 0; + int chunks_partial = 0; + + memPoolClean(pool, (time_t) 555555, -1); /* don't want to get chunks released before reporting */ + stats->pool = pool; + stats->label = pool->label; + stats->meter = &pool->meter; + stats->obj_size = pool->obj_size; + stats->chunk_capacity = pool->chunk_capacity; + + stats->chunks_alloc += pool->chunkCount; + stats->overhead += sizeof(MemPool) + sizeof(MemPool *) + pool->chunkCount * sizeof(MemChunk); + stats->mem_idle_limit = mem_idle_limit; chunk = pool->Chunks; while (chunk) { if (chunk->inuse_count == 0) - mp_st->chunks_free++; + chunks_free++; else if (chunk->inuse_count < pool->chunk_capacity) - mp_st->chunks_partial++; + chunks_partial++; chunk = chunk->next; } - mp_st->chunks_inuse = pool->chunkCount - mp_st->chunks_free; + stats->chunks_free += chunks_free; + stats->chunks_partial += chunks_partial; - mp_st->items_alloc = pool->meter.alloc.level; - mp_st->items_inuse = pool->meter.inuse.level; - mp_st->items_idle = pool->meter.idle.level; + stats->chunks_inuse += pool->chunkCount - chunks_free; - return index + 1; + stats->items_alloc += pool->meter.alloc.level; + stats->items_inuse += pool->meter.inuse.level; + stats->items_idle += pool->meter.idle.level; } -static int -memPoolInUseCount(const MemPool * pool) +/* + * Get Pool accounting statistics either by pool or by index + * If neither is specified, Totals statistics is returned + */ +int +memPoolGetStats(MemPoolStats * stats, MemPool * pool, int index) { - assert(pool); - memPoolFlushMeters((MemPool *) pool); - return pool->meter.inuse.level; + int i; + memset(stats, 0, sizeof(MemPoolStats)); + if (index >= PoolArray.count) + return 0; + if (pool) { + memPoolGetStatsOne(stats, pool); + return 0; + } + if (index >= 0) { + pool = PoolArray.items[index]; + if (!pool) + return index + 1; + memPoolGetStatsOne(stats, pool); + return index + 1; + } + /* index < 0 && pool==NULL */ + /* gather all stats for Totals */ + memPoolFlushMeters(NULL); /* recreate TheMeter */ + for (i = 0; i < PoolArray.count; i++) { + pool = PoolArray.items[i]; + memPoolGetStatsOne(stats, pool); + } + stats->pool = NULL; + stats->label = "Totals"; + stats->chunk_capacity = 0; + stats->obj_size = 0; + stats->overhead += sizeof(Array) + PoolArray.capacity * sizeof(MemPool *); + stats->mem_idle_limit = mem_idle_limit; + stats->meter = &TheMeter; + return i; } static void Index: squid/src/MemPoolStats.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/MemPoolStats.c,v retrieving revision 1.1.2.17 retrieving revision 1.1.2.18 diff -u -r1.1.2.17 -r1.1.2.18 --- squid/src/MemPoolStats.c 2 May 2001 20:21:59 -0000 1.1.2.17 +++ squid/src/MemPoolStats.c 3 May 2001 14:31:40 -0000 1.1.2.18 @@ -38,78 +38,15 @@ #include "MemPool.h" /* module globals */ -void memConfigure(void); -void memPoolCleanIdlePools(void *unused); -void memInitModule(void); -void memCleanModule(void); void memReport(StoreEntry * e); /* module locals */ -static double clean_interval = 15.0; /* time to live of idle chunk before release */ static double xm_time = 0; static double xm_deltat = 0; -/* huge constant to set mem_idle_limit to "unlimited" */ -static const size_t mem_unlimited_size = 2 * 1024 * MB; - /* local prototypes */ static void memPoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, StoreEntry * e); -static double -toMB(size_t size) -{ - return ((double) size) / MB; -} - -static size_t -toKB(size_t size) -{ - return (size + 1024 - 1) / 1024; -} - -/* Initialization */ - -/* XXX This is NOT statistics. Does NOT belong here. */ -void -memConfigure(void) -{ - size_t new_pool_limit; - /* set to configured value first */ - if (!Config.onoff.mem_pools) - new_pool_limit = 0; - else if (Config.MemPools.limit > 0) - new_pool_limit = Config.MemPools.limit; - else - new_pool_limit = mem_unlimited_size; - if (memPoolSetIdleLimit(new_pool_limit) > 0) - debug(63, 1) ("Shrinking idle mem pools to %.2f MB\n", toMB(new_pool_limit)); -} - -/* XXX This is NOT statistics. Does NOT belong here. */ -void -memPoolCleanIdlePools(void *unused) -{ - memPoolClean(NULL, clean_interval); - eventAdd("memPoolCleanIdlePools", memPoolCleanIdlePools, NULL, clean_interval, 1); -} - -void -memInitModule(void) -{ - debug(63, 1) ("Memory pools are '%s'; limit: %.2f MB\n", - (Config.onoff.mem_pools ? "on" : "off"), toMB(memPoolIdleLimit())); - xm_time = current_dtime; -} - -void -memCleanModule(void) -{ - int dirty_count = 0; - dirty_count = memPoolCleanModule(); - if (dirty_count) - debug(63, 2) ("memCleanModule: %d pools are left dirty\n", dirty_count); -} - #if UNUSED_CODE /* to-do: make debug level a parameter? */ static void @@ -192,7 +129,6 @@ static char buf[64]; static MemPoolStats mp_stats; static MemPoolStats mp_total; - static MemPoolMeter *AllMeter; /* caption */ storeAppendPrintf(e, "Current memory usage:\n"); @@ -217,40 +153,26 @@ "\n"); xm_deltat = current_dtime - xm_time; xm_time = current_dtime; - memPoolFlushMeters(NULL); - /* prepare Totals report line */ - memset(&mp_total, 0, sizeof(MemPoolStats)); - memPoolGetTheMeter(&AllMeter); - mp_total.label = "Total"; - mp_total.meter = AllMeter; + /* Get stats for Totals report line */ + memPoolGetStats(&mp_total, NULL, -1); mp_total.obj_size = 1; /* main table */ i = 0; - while (memPoolGetStats(&mp_stats, i++)) { + while (memPoolGetStats(&mp_stats, NULL, i++)) { if (!mp_stats.pool) /* pool destroyed */ continue; if (mp_stats.pool->meter.inuse.hwater_level > 0) /* this pool has been used */ - memPoolReport(&mp_stats, AllMeter, e); - mp_total.chunks_alloc += mp_stats.chunks_alloc; - mp_total.chunks_free += mp_stats.chunks_free; - mp_total.chunks_inuse += mp_stats.chunks_inuse; - mp_total.chunks_partial += mp_stats.chunks_partial; - - mp_total.items_alloc += mp_stats.items_alloc; - mp_total.items_inuse += mp_stats.items_inuse; - mp_total.items_idle += mp_stats.items_idle; - mp_total.overhead += mp_stats.overhead + strlen(mp_stats.label) + 1; + memPoolReport(&mp_stats, mp_total.meter, e); } - mp_total.overhead += memPoolGetOverhead(); - memPoolReport(&mp_total, AllMeter, e); + memPoolReport(&mp_total, mp_total.meter, e); /* Cumulative */ - storeAppendPrintf(e, "Cumulative allocated volume: %s\n", double_to_str(buf, 64, AllMeter->gb_saved.bytes)); + storeAppendPrintf(e, "Cumulative allocated volume: %s\n", double_to_str(buf, 64, mp_total.meter->gb_saved.bytes)); /* overhead */ storeAppendPrintf(e, "Current overhead: %d bytes (%.3f%%)\n", - mp_total.overhead, xpercent(mp_total.overhead, AllMeter->inuse.level)); + mp_total.overhead, xpercent(mp_total.overhead, mp_total.meter->inuse.level)); /* limits */ - storeAppendPrintf(e, "Idle pool limit: %.2f MB\n", toMB(memPoolIdleLimit())); + storeAppendPrintf(e, "Idle pool limit: %.2f MB\n", toMB(mp_total.mem_idle_limit)); } Index: squid/src/mem.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/mem.c,v retrieving revision 1.9.8.5 retrieving revision 1.9.8.6 diff -u -r1.9.8.5 -r1.9.8.6 --- squid/src/mem.c 27 Apr 2001 09:14:19 -0000 1.9.8.5 +++ squid/src/mem.c 3 May 2001 14:31:40 -0000 1.9.8.6 @@ -1,6 +1,6 @@ /* - * $Id: mem.c,v 1.9.8.5 2001/04/27 09:14:19 akroonmaa Exp $ + * $Id: mem.c,v 1.9.8.6 2001/05/03 14:31:40 akroonmaa Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -108,6 +108,23 @@ * public routines */ +int +memPoolInUseCount(MemPool * pool) +{ + MemPoolStats stats; + assert(pool); + memPoolGetStats(&stats, pool, -1); + return stats.items_inuse; +} + +int +memPoolsTotalAllocated(void) +{ + MemPoolStats stats; + memPoolGetStats(&stats, NULL, -1); + return stats.meter->alloc.level; +} + /* * we have a limit on _total_ amount of idle memory so we ignore * max_pages for now @@ -174,11 +191,43 @@ pool ? memPoolFree(pool, buf) : xfree(buf); } +static double clean_interval = 15.0; /* time to live of idle chunk before release */ + +void +memPoolCleanIdlePools(void *unused) +{ + memPoolClean(NULL, clean_interval, -1); + eventAdd("memPoolCleanIdlePools", memPoolCleanIdlePools, NULL, clean_interval, 1); +} + +static int mem_idle_limit = 0; + +void +memConfigure(void) +{ + int new_pool_limit; + /* set to configured value first */ + if (!Config.onoff.mem_pools) + new_pool_limit = 0; + else if (Config.MemPools.limit > 0) + new_pool_limit = Config.MemPools.limit; + else + new_pool_limit = mem_unlimited_size; + + if (mem_idle_limit > new_pool_limit) + debug(63, 1) ("Shrinking idle mem pools to %.2f MB\n", toMB(new_pool_limit)); + memPoolClean(NULL, 0, new_pool_limit); + mem_idle_limit = new_pool_limit; +} + void memInit(void) { int i; - memInitModule(); + memPoolInit(); + debug(63, 1) ("Memory pools are '%s'; limit: %.2f MB\n", + (Config.onoff.mem_pools ? "on" : "off"), toMB(mem_idle_limit)); + /* set all pointers to null */ memset(MemPools, '\0', sizeof(MemPools)); /* @@ -279,7 +328,11 @@ void memClean(void) { - memCleanModule(); + MemPoolStats stats; + memPoolClean(NULL, 0, 0); + memPoolGetStats(&stats, NULL, -1); + if (stats.items_inuse) + debug(63, 2) ("memCleanModule: %d items in %d chunks are left dirty\n", stats.items_inuse, stats.chunks_inuse); } int Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.23.4.7 retrieving revision 1.23.4.8 diff -u -r1.23.4.7 -r1.23.4.8 --- squid/src/protos.h 2 May 2001 20:21:59 -0000 1.23.4.7 +++ squid/src/protos.h 3 May 2001 14:31:40 -0000 1.23.4.8 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.23.4.7 2001/05/02 20:21:59 akroonmaa Exp $ + * $Id: protos.h,v 1.23.4.8 2001/05/03 14:31:40 akroonmaa Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -833,10 +833,14 @@ extern void memCheckInit(void); /* MemPool */ -extern int memPoolControl(void **pool, int cmd, size_t value); extern MemPool *memPoolCreate(const char *label, size_t obj_size); +extern void memPoolTune(MemPool * pool, size_t chunksize, int unused); extern void *memPoolAlloc(MemPool * pool); extern void memPoolFree(MemPool * pool, void *obj); +extern void memPoolDestroy(MemPool * pool); +extern int memPoolGetStats(MemPoolStats * stats, MemPool * pool, int index); +extern void memPoolInit(void); +extern void memPoolClean(MemPool * pool, time_t maxage, int new_idle_limit); /* Mem */ extern void memReport(StoreEntry * e); Index: squid/src/stat.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/stat.c,v retrieving revision 1.9.8.4 retrieving revision 1.9.8.5 diff -u -r1.9.8.4 -r1.9.8.5 --- squid/src/stat.c 30 Apr 2001 21:14:53 -0000 1.9.8.4 +++ squid/src/stat.c 3 May 2001 14:31:40 -0000 1.9.8.5 @@ -1,6 +1,6 @@ /* - * $Id: stat.c,v 1.9.8.4 2001/04/30 21:14:53 akroonmaa Exp $ + * $Id: stat.c,v 1.9.8.5 2001/05/03 14:31:40 akroonmaa Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -601,11 +601,18 @@ storeAppendPrintf(sentry, "\tTotal accounted: %6d KB\n", statMemoryAccounted() >> 10); #endif - storeAppendPrintf(sentry, "\tmemPoolAlloc calls: %9d\n", - mem_pool_alloc_calls); - storeAppendPrintf(sentry, "\tmemPoolFree calls: %9d\n", - mem_pool_free_calls); - + { + MemPoolStats mp_stats; + memPoolGetStats(&mp_stats, NULL, -1); + storeAppendPrintf(sentry, "\tmemPool accounted: %6d KB %3d%%\n", + mp_stats.meter->alloc.level >> 10, percent(mp_stats.meter->alloc.level, t)); + storeAppendPrintf(sentry, "\tmemPool unaccounted: %6d KB %3d%%\n", + (t - mp_stats.meter->alloc.level) >> 10, percent((t - mp_stats.meter->alloc.level), t)); + storeAppendPrintf(sentry, "\tmemPoolAlloc calls: %9.0f\n", + mp_stats.meter->gb_saved.count); + storeAppendPrintf(sentry, "\tmemPoolFree calls: %9.0f\n", + mp_stats.meter->gb_freed.count); + } storeAppendPrintf(sentry, "File descriptor usage for %s:\n", appname); storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4d\n", Squid_MaxFD); @@ -1526,6 +1533,7 @@ GENGRAPH(select_loops, "select_loops", "System Select Loop calls/sec"); GENGRAPH(cputime, "cputime", "CPU utilisation"); } + #endif /* STAT_GRAPHS */ int