Since, in all practical uses the mem-usage of squid tends to grow and
then stabilise, I've changed the behaviour of mempool a bit to allocate
in larger chunks as the usage grows. This effectively reduces overhead
and fragmentation.
diff -u -b -r squid-1.2.beta24/src/MemPool.c squid-BuGless/src/MemPool.c
--- squid-1.2.beta24/src/MemPool.c Wed Jul 22 22:36:52 1998
+++ squid-BuGless/src/MemPool.c Mon Aug 24 12:57:48 1998
@@ -204,7 +204,7 @@
assert(label && obj_size);
pool->label = label;
pool->obj_size = obj_size;
- stackInit(&pool->pstack);
+ pool->pstack = 0;
/* other members are set to 0 */
stackPush(&Pools, pool);
return pool;
@@ -218,54 +218,78 @@
memPoolDestroy(MemPool * pool)
{
assert(pool);
- stackClean(&pool->pstack);
xfree(pool);
}
void *
memPoolAlloc(MemPool * pool)
{
+ void*obj;
assert(pool);
memMeterInc(pool->meter.inuse);
memMeterAdd(TheMeter.inuse, pool->obj_size);
gb_inc(&mem_traffic_volume, pool->obj_size);
+#ifdef NEVERFREE
+ if (!(obj = pool->pstack)) {
+ unsigned step = pool->meter.alloc.level/4+1; /* 25% growth */
+ if (step*pool->obj_size>256*1024)
+ step = 256*1024/pool->obj_size; /* but at most 256KB at a time */
+ obj = xmalloc(step*pool->obj_size);
+ memMeterAdd(pool->meter.alloc, step);
+ memMeterAdd(TheMeter.alloc, step*pool->obj_size);
+ while(--step) {
+ memPoolFree(pool, obj);
+ obj=(char*)obj+pool->obj_size;
+ memMeterInc(pool->meter.inuse);
+ memMeterAdd(TheMeter.inuse, pool->obj_size);
+ }
+#else
if (pool->pstack.count) {
+ assert(!pool->meter.idle.level);
+ return xcalloc(1, pool->obj_size);
+#endif
+ } else {
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);
+ pool->pstack = *(void**)obj;
}
+ memset(obj, 0, pool->obj_size);
+ return obj;
}
void
memPoolFree(MemPool * pool, void *obj)
{
assert(pool && obj);
+ assert(pool->obj_size >= sizeof pool->pstack);
memMeterDec(pool->meter.inuse);
memMeterDel(TheMeter.inuse, pool->obj_size);
+#ifdef NEVERFREE
+ if (1) {
+#else
if (TheMeter.idle.level + pool->obj_size <= mem_idle_limit) {
+#endif
memMeterInc(pool->meter.idle);
memMeterAdd(TheMeter.idle, pool->obj_size);
- memset(obj, 0, pool->obj_size);
- stackPush(&pool->pstack, obj);
+ *(void**)obj = pool->pstack;
+ pool->pstack = obj;
} else {
memMeterDec(pool->meter.alloc);
memMeterDel(TheMeter.alloc, pool->obj_size);
xfree(obj);
}
+#if 0 /* bogus assertion? srb */
assert(pool->meter.idle.level <= pool->meter.alloc.level);
+#endif
}
static void
memPoolShrink(MemPool * pool, size_t new_limit)
{
+#ifndef NEVERFREE
assert(pool);
assert(new_limit >= 0);
while (pool->meter.idle.level > new_limit && pool->pstack.count > 0) {
@@ -276,6 +300,7 @@
xfree(stackPop(&pool->pstack));
}
assert(pool->meter.idle.level <= new_limit); /* paranoid */
+#endif
}
int
@@ -355,8 +380,7 @@
idle_count += pool->meter.idle.level;
}
overhd_size += sizeof(MemPool) + sizeof(MemPool *) +
- strlen(pool->label) + 1 +
- pool->pstack.capacity * sizeof(void *);
+ strlen(pool->label) + 1;
}
overhd_size += sizeof(Pools) + Pools.capacity * sizeof(MemPool *);
/* totals */
diff -u -b -r squid-1.2.beta24/src/structs.h squid-BuGless/src/structs.h
--- squid-1.2.beta24/src/structs.h Fri Aug 21 06:03:49 1998
+++ squid-BuGless/src/structs.h Sat Aug 22 03:32:32 1998
@@ -1435,7 +1470,7 @@
struct _MemPool {
const char *label;
size_t obj_size;
- Stack pstack; /* stack for free pointers */
+ void*pstack; /* stack for free pointers */
MemPoolMeter meter;
};
-- Sincerely, srb@cuci.nl Stephen R. van den Berg (AKA BuGless). This signature third word omitted, yet is comprehensible.Received on Tue Jul 29 2003 - 13:15:52 MDT
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:11:52 MST