]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Enable string mempools to work correctly during initialization phase
authorFrancesco Chemolli <kinkie@squid-cache.org>
Wed, 6 Apr 2011 10:40:10 +0000 (12:40 +0200)
committerFrancesco Chemolli <kinkie@squid-cache.org>
Wed, 6 Apr 2011 10:40:10 +0000 (12:40 +0200)
Makes string mempools work before Mem::Init() was called, as may happen
during global variable initialization or early main.cc processing. If
needed, strings allocated before the Mem::Init() call are given an extra
buffer space to make sure the allocated buffer size will not match any
string pool size during deallocation.
Shortcomings: We now waste RAM on buffer increase for early allocated
strings unless they are already bigger than the maximum supported string
pool size. Statistics for early allocations are broken. Non-string
mempools still do not support early allocations.

src/mem.cc

index 61680473a3e47637dcf07d2222e297cf04b4b9a8..9a0c1cb44283989e539dafd731da617aaa2ffc41 100644 (file)
@@ -61,9 +61,16 @@ static MemAllocator *MemPools[MEM_MAX];
 static double xm_time = 0;
 static double xm_deltat = 0;
 
+/* all pools are ready to be used */
+static bool MemIsInitialized = false;
+
 /* string pools */
 #define mem_str_pool_count 3
 
+// 4 bytes bigger than the biggest string pool size
+// which is in turn calculated from SmallestStringBeforeMemIsInitialized
+static const size_t SmallestStringBeforeMemIsInitialized = 516;
+
 static const struct {
     const char *name;
     size_t obj_size;
@@ -78,7 +85,8 @@ StrPoolsAttrs[mem_str_pool_count] = {
         "Medium Strings", MemAllocator::RoundedSize(128),
     },                         /* to fit most urls */
     {
-        "Long Strings", MemAllocator::RoundedSize(512)
+        "Long Strings", 
+        MemAllocator::RoundedSize(SmallestStringBeforeMemIsInitialized-4)
     }                          /* other */
 };
 
@@ -190,14 +198,20 @@ memFree(void *p, int type)
     MemPools[type]->freeOne(p);
 }
 
-/* allocate a variable size buffer using best-fit pool */
+/* allocate a variable size buffer using best-fit string pool */
 void *
 memAllocString(size_t net_size, size_t * gross_size)
 {
-    int i;
     MemAllocator *pool = NULL;
     assert(gross_size);
 
+    // if pools are not yet ready, make sure that
+    // the requested size is not poolable so that the right deallocator
+    // will be used
+    if (!MemIsInitialized && net_size < SmallestStringBeforeMemIsInitialized)
+       net_size = SmallestStringBeforeMemIsInitialized;
+
+    unsigned int i;
     for (i = 0; i < mem_str_pool_count; ++i) {
         if (net_size <= StrPoolsAttrs[i].obj_size) {
             pool = StrPools[i].pool;
@@ -207,6 +221,7 @@ 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);
     return pool ? pool->alloc() : xcalloc(1, net_size);
@@ -228,18 +243,20 @@ memStringCount()
 void
 memFreeString(size_t size, void *buf)
 {
-    int i;
     MemAllocator *pool = NULL;
-    assert(size && buf);
-
-    for (i = 0; i < mem_str_pool_count; ++i) {
-        if (size <= StrPoolsAttrs[i].obj_size) {
-            assert(size == StrPoolsAttrs[i].obj_size);
-            pool = StrPools[i].pool;
-            break;
+    assert(buf);
+
+    if (MemIsInitialized) {
+        for (unsigned int i = 0; i < mem_str_pool_count; ++i) {
+            if (size <= StrPoolsAttrs[i].obj_size) {
+                assert(size == StrPoolsAttrs[i].obj_size);
+                pool = StrPools[i].pool;
+                break;
+            }
         }
     }
 
+    // may forget [de]allocations until MemIsInitialized
     memMeterDec(StrCountMeter);
     memMeterDel(StrVolumeMeter, size);
     pool ? pool->freeOne(buf) : xfree(buf);
@@ -438,6 +455,7 @@ Mem::Init(void)
             debugs(13, 1, "Notice: " << StrPoolsAttrs[i].name << " is " << StrPools[i].pool->objectSize() << " bytes instead of requested " << StrPoolsAttrs[i].obj_size << " bytes");
     }
 
+    MemIsInitialized = true;
     /** \par
      * finally register with the cache manager */
     RegisterWithCacheManager();