--------------------- PatchSet 2140 Date: 2001/04/28 23:46:57 Author: hno Branch: chunked_mempools Tag: (none) Log: Deleted unused src/MemPool.c Members: src/MemPool.c:1.5->1.5.20.1(DEAD) --- squid/src/MemPool.c Wed Feb 14 00:52:51 2007 +++ /dev/null Wed Feb 14 00:51:37 2007 @@ -1,383 +0,0 @@ - -/* - * $Id: MemPool.c,v 1.5 2001/01/12 08:20:32 hno Exp $ - * - * DEBUG: section 63 Low Level Memory Pool Management - * AUTHOR: Alex Rousskov - * - * SQUID Web Proxy Cache http://www.squid-cache.org/ - * ---------------------------------------------------------- - * - * Squid is the result of efforts by numerous individuals from - * the Internet community; see the CONTRIBUTORS file for full - * details. Many organizations have provided support for Squid's - * development; see the SPONSORS file for full details. Squid is - * Copyrighted (C) 2001 by the Regents of the University of - * California; see the COPYRIGHT file for full details. Squid - * incorporates software developed and/or copyrighted by other - * sources; see the CREDITS file for full details. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. - * - */ - - -#include "squid.h" -#include "Stack.h" - -#define MB ((size_t)1024*1024) - -/* exported */ -unsigned int mem_pool_alloc_calls = 0; -unsigned int mem_pool_free_calls = 0; - -/* module globals */ - -/* huge constant to set mem_idle_limit to "unlimited" */ -static const size_t mem_unlimited_size = 2 * 1024 * MB; - -/* we cannot keep idle more than this limit */ -static size_t mem_idle_limit = 0; - -/* memory pool accounting */ -static MemPoolMeter TheMeter; -static gb_t mem_traffic_volume = -{0, 0}; -static Stack Pools; - -/* local prototypes */ -static void memShrink(ssize_t new_limit); -static void memPoolDescribe(const MemPool * pool); -static void memPoolShrink(MemPool * pool, ssize_t new_limit); - - -static double -toMB(size_t size) -{ - return ((double) size) / MB; -} - -static size_t -toKB(size_t size) -{ - return (size + 1024 - 1) / 1024; -} - - -/* Initialization */ - -void -memConfigure(void) -{ - size_t new_pool_limit = mem_idle_limit; - /* set to configured value first */ -#if PURIFY - debug(63, 1) ("Disabling Memory pools under purify\n"); - Config.onoff.mem_pools = 0; -#endif - 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; - /* shrink memory pools if needed */ - if (TheMeter.idle.level > new_pool_limit) { - debug(63, 1) ("Shrinking idle mem pools to %.2f MB\n", toMB(new_pool_limit)); - memShrink(new_pool_limit); - } - assert(TheMeter.idle.level <= new_pool_limit); - mem_idle_limit = new_pool_limit; -} - -void -memInitModule(void) -{ - memset(&TheMeter, 0, sizeof(TheMeter)); - stackInit(&Pools); - debug(63, 1) ("Memory pools are '%s'; limit: %.2f MB\n", - (Config.onoff.mem_pools ? "on" : "off"), toMB(mem_idle_limit)); -} - -void -memCleanModule(void) -{ - int i; - int dirty_count = 0; - for (i = 0; i < Pools.count; i++) { - MemPool *pool = Pools.items[i]; - if (memPoolInUseCount(pool)) { - memPoolDescribe(pool); - dirty_count++; - } else { - memPoolDestroy(pool); - Pools.items[i] = NULL; - } - } - if (dirty_count) - debug(63, 2) ("memCleanModule: %d pools are left dirty\n", dirty_count); - /* we clean the stack anyway */ - stackClean(&Pools); -} - - -static void -memShrink(ssize_t new_limit) -{ - ssize_t start_limit = TheMeter.idle.level; - int i; - assert(start_limit >= 0 && new_limit >= 0); - debug(63, 1) ("memShrink: started with %d KB goal: %d KB\n", - toKB(TheMeter.idle.level), toKB(new_limit)); - /* first phase: cut proportionally to the pool idle size */ - for (i = 0; i < Pools.count && TheMeter.idle.level > new_limit; ++i) { - MemPool *pool = Pools.items[i]; - const ssize_t target_pool_size = (size_t) ((double) pool->meter.idle.level * new_limit) / start_limit; - memPoolShrink(pool, target_pool_size); - } - debug(63, 1) ("memShrink: 1st phase done with %d KB left\n", toKB(TheMeter.idle.level)); - /* second phase: cut to 0 */ - for (i = 0; i < Pools.count && TheMeter.idle.level > new_limit; ++i) - memPoolShrink(Pools.items[i], 0); - debug(63, 1) ("memShrink: 2nd phase done with %d KB left\n", toKB(TheMeter.idle.level)); - assert(TheMeter.idle.level <= new_limit); /* paranoid */ -} - -/* MemPoolMeter */ - -static void -memPoolMeterReport(const MemPoolMeter * pm, size_t obj_size, - int alloc_count, int inuse_count, int idle_count, StoreEntry * e) -{ - assert(pm); - storeAppendPrintf(e, "%d\t %d\t %d\t %.2f\t %d\t %d\t %d\t %d\t %d\t %d\t %d\t %d\t %d\t %.2f\t %.2f\t %.2f\t %d\n", - /* alloc */ - alloc_count, - toKB(obj_size * pm->alloc.level), - toKB(obj_size * pm->alloc.hwater_level), - (double) ((squid_curtime - pm->alloc.hwater_stamp) / 3600.), - xpercentInt(obj_size * pm->alloc.level, TheMeter.alloc.level), - /* in use */ - inuse_count, - toKB(obj_size * pm->inuse.level), - toKB(obj_size * pm->inuse.hwater_level), - xpercentInt(pm->inuse.level, pm->alloc.level), - /* idle */ - idle_count, - toKB(obj_size * pm->idle.level), - toKB(obj_size * pm->idle.hwater_level), - /* (int)rint(xpercent(pm->idle.level, pm->alloc.level)), */ - /* saved */ - pm->saved.count, - xpercent(pm->saved.count, mem_traffic_volume.count), - xpercent(obj_size * gb_to_double(&pm->saved), gb_to_double(&mem_traffic_volume)), - xpercent(pm->saved.count, pm->total.count), - pm->total.count); -} - -/* MemMeter */ - -void -memMeterSyncHWater(MemMeter * m) -{ - assert(m); - if (m->hwater_level < m->level) { - m->hwater_level = m->level; - m->hwater_stamp = squid_curtime; - } -} - -/* MemPool */ - -MemPool * -memPoolCreate(const char *label, size_t obj_size) -{ - MemPool *pool = xcalloc(1, sizeof(MemPool)); - assert(label && obj_size); - pool->label = label; - pool->obj_size = obj_size; - stackInit(&pool->pstack); - /* other members are set to 0 */ - stackPush(&Pools, pool); - return pool; -} - -/* - * warning: we do not clean this entry from Pools stack assuming memPoolDestroy - * is used at the end of the program only - */ -void -memPoolDestroy(MemPool * pool) -{ - assert(pool); - stackClean(&pool->pstack); - xfree(pool); -} - -void * -memPoolAlloc(MemPool * pool) -{ - assert(pool); - memMeterInc(pool->meter.inuse); - gb_inc(&pool->meter.total, 1); - gb_inc(&TheMeter.total, pool->obj_size); - memMeterAdd(TheMeter.inuse, pool->obj_size); - gb_inc(&mem_traffic_volume, pool->obj_size); - mem_pool_alloc_calls++; - if (pool->pstack.count) { - assert(pool->meter.idle.level); - memMeterDec(pool->meter.idle); - memMeterDel(TheMeter.idle, pool->obj_size); - gb_inc(&pool->meter.saved, 1); - gb_inc(&TheMeter.saved, pool->obj_size); - return stackPop(&pool->pstack); - } else { - assert(!pool->meter.idle.level); - memMeterInc(pool->meter.alloc); - memMeterAdd(TheMeter.alloc, pool->obj_size); - return xcalloc(1, pool->obj_size); - } -} - -void -memPoolFree(MemPool * pool, void *obj) -{ - assert(pool && obj); - memMeterDec(pool->meter.inuse); - memMeterDel(TheMeter.inuse, pool->obj_size); - mem_pool_free_calls++; - if (TheMeter.idle.level + pool->obj_size <= mem_idle_limit) { - memMeterInc(pool->meter.idle); - memMeterAdd(TheMeter.idle, pool->obj_size); - memset(obj, 0, pool->obj_size); - stackPush(&pool->pstack, obj); - } else { - memMeterDec(pool->meter.alloc); - memMeterDel(TheMeter.alloc, pool->obj_size); - xfree(obj); - } - assert(pool->meter.idle.level <= pool->meter.alloc.level); -} - -static void -memPoolShrink(MemPool * pool, ssize_t new_limit) -{ - assert(pool); - assert(new_limit >= 0); - while (pool->meter.idle.level > new_limit && pool->pstack.count > 0) { - memMeterDec(pool->meter.alloc); - memMeterDec(pool->meter.idle); - memMeterDel(TheMeter.idle, pool->obj_size); - memMeterDel(TheMeter.alloc, pool->obj_size); - xfree(stackPop(&pool->pstack)); - } - assert(pool->meter.idle.level <= new_limit); /* paranoid */ -} - -int -memPoolWasUsed(const MemPool * pool) -{ - assert(pool); - return pool->meter.alloc.hwater_level > 0; -} - -int -memPoolInUseCount(const MemPool * pool) -{ - assert(pool); - return pool->meter.inuse.level; -} - -size_t -memPoolInUseSize(const MemPool * pool) -{ - assert(pool); - return pool->obj_size * pool->meter.inuse.level; -} - -/* to-do: make debug level a parameter? */ -static void -memPoolDescribe(const MemPool * pool) -{ - assert(pool); - debug(63, 2) ("%-20s: %6d x %4d bytes = %5d KB\n", - pool->label, memPoolInUseCount(pool), pool->obj_size, - toKB(memPoolInUseSize(pool))); -} - -size_t -memTotalAllocated(void) -{ - return TheMeter.alloc.level; -} - -void -memPoolReport(const MemPool * pool, StoreEntry * e) -{ - assert(pool); - storeAppendPrintf(e, "%-20s\t %4d\t ", - pool->label, pool->obj_size); - memPoolMeterReport(&pool->meter, pool->obj_size, - pool->meter.alloc.level, pool->meter.inuse.level, pool->meter.idle.level, - e); -} - -void -memReport(StoreEntry * e) -{ - size_t overhd_size = 0; - int alloc_count = 0; - int inuse_count = 0; - int idle_count = 0; - int i; - /* caption */ - storeAppendPrintf(e, "Current memory usage:\n"); - /* heading */ - storeAppendPrintf(e, "Pool\t Obj Size\t" - "Allocated\t\t\t\t\t In Use\t\t\t\t Idle\t\t\t Allocations Saved\t\t\t Hit Rate\t\n" - " \t (bytes)\t" - "(#)\t (KB)\t high (KB)\t high (hrs)\t impact (%%total)\t" - "(#)\t (KB)\t high (KB)\t portion (%%alloc)\t" - "(#)\t (KB)\t high (KB)\t" - "(number)\t (%%num)\t (%%vol)\t" - "(%%num)\t" - "(number)" - "\n"); - /* main table */ - for (i = 0; i < Pools.count; i++) { - const MemPool *pool = Pools.items[i]; - if (memPoolWasUsed(pool)) { - memPoolReport(pool, e); - alloc_count += pool->meter.alloc.level; - inuse_count += pool->meter.inuse.level; - idle_count += pool->meter.idle.level; - } - overhd_size += sizeof(MemPool) + sizeof(MemPool *) + - strlen(pool->label) + 1 + - pool->pstack.capacity * sizeof(void *); - } - overhd_size += sizeof(Pools) + Pools.capacity * sizeof(MemPool *); - /* totals */ - storeAppendPrintf(e, "%-20s\t %-4s\t ", "Total", "-"); - memPoolMeterReport(&TheMeter, 1, alloc_count, inuse_count, idle_count, e); - storeAppendPrintf(e, "Cumulative allocated volume: %s\n", gb_to_str(&mem_traffic_volume)); - /* overhead */ - storeAppendPrintf(e, "Current overhead: %d bytes (%.3f%%)\n", - overhd_size, xpercent(overhd_size, TheMeter.inuse.level)); - /* limits */ - storeAppendPrintf(e, "Idle pool limit: %.2f MB\n", toMB(mem_idle_limit)); - storeAppendPrintf(e, "memPoolAlloc calls: %d\n", mem_pool_alloc_calls); - storeAppendPrintf(e, "memPoolFree calls: %d\n", mem_pool_free_calls); -}