]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/mem/old_api.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / mem / old_api.cc
index 6e2b93d38abf42703bd4e209ab434c9cafd3faac..0561a755358e4b42e1406adec8a74e8d1bc3091f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -9,8 +9,6 @@
 /* DEBUG: section 13    High Level Memory Pool Management */
 
 #include "squid.h"
-#include "acl/AclDenyInfoList.h"
-#include "acl/AclNameList.h"
 #include "base/PackableStream.h"
 #include "ClientInfo.h"
 #include "dlink.h"
@@ -24,7 +22,6 @@
 #include "MemBuf.h"
 #include "mgr/Registration.h"
 #include "SquidConfig.h"
-#include "SquidList.h"
 #include "SquidTime.h"
 #include "Store.h"
 
@@ -38,60 +35,21 @@ static void memFree16K(void *);
 static void memFree32K(void *);
 static void memFree64K(void *);
 
-/* module globals */
-const size_t squidSystemPageSize=getpagesize();
-
 /* local prototypes */
 static void memStringStats(std::ostream &);
 
 /* module locals */
-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 6
 
-// 4 bytes bigger than the biggest string pool size
-// which is in turn calculated from SmallestStringBeforeMemIsInitialized
-static const size_t SmallestStringBeforeMemIsInitialized = 1024*16+4;
-
-static const struct {
+struct PoolMeta {
     const char *name;
     size_t obj_size;
-}
-
-StrPoolsAttrs[mem_str_pool_count] = {
-
-    {
-        "Short Strings", MemAllocator::RoundedSize(36),
-    },              /* to fit rfc1123 and similar */
-    {
-        "Medium Strings", MemAllocator::RoundedSize(128),
-    },              /* to fit most urls */
-    {
-        "Long Strings", MemAllocator::RoundedSize(512),
-    },
-    {
-        "1KB Strings", MemAllocator::RoundedSize(1024),
-    },
-    {
-        "4KB Strings", MemAllocator::RoundedSize(4*1024),
-    },
-    {
-        "16KB Strings",
-        MemAllocator::RoundedSize(SmallestStringBeforeMemIsInitialized-4)
-    }
 };
 
-static struct {
-    MemAllocator *pool;
-}
-
-StrPools[mem_str_pool_count];
 static Mem::Meter StrCountMeter;
 static Mem::Meter StrVolumeMeter;
 
@@ -100,6 +58,80 @@ static Mem::Meter HugeBufVolumeMeter;
 
 /* local routines */
 
+// XXX: refactor objects using these pools to use MEMPROXY classes instead
+// then remove this function entirely
+static MemAllocator *&
+GetPool(size_t type)
+{
+    static MemAllocator *pools[MEM_MAX];
+    static bool initialized = false;
+
+    if (!initialized) {
+        memset(pools, '\0', sizeof(pools));
+        initialized = true;
+        // Mem::Init() makes use of GetPool(type) to initialize
+        // the actual pools. So must come after the flag is true
+        Mem::Init();
+    }
+
+    return pools[type];
+}
+
+static MemAllocator &
+GetStrPool(size_t type)
+{
+    static MemAllocator *strPools[mem_str_pool_count];
+    static bool initialized = false;
+
+    static const PoolMeta PoolAttrs[mem_str_pool_count] = {
+        {"Short Strings", MemAllocator::RoundedSize(36)},      /* to fit rfc1123 and similar */
+        {"Medium Strings", MemAllocator::RoundedSize(128)},    /* to fit most urls */
+        {"Long Strings", MemAllocator::RoundedSize(512)},
+        {"1KB Strings", MemAllocator::RoundedSize(1024)},
+        {"4KB Strings", MemAllocator::RoundedSize(4*1024)},
+        {"16KB Strings", MemAllocator::RoundedSize(16*1024)}
+    };
+
+    if (!initialized) {
+        memset(strPools, '\0', sizeof(strPools));
+
+        /** Lastly init the string pools. */
+        for (int i = 0; i < mem_str_pool_count; ++i) {
+            strPools[i] = memPoolCreate(PoolAttrs[i].name, PoolAttrs[i].obj_size);
+            strPools[i]->zeroBlocks(false);
+
+            if (strPools[i]->objectSize() != PoolAttrs[i].obj_size)
+                debugs(13, DBG_IMPORTANT, "NOTICE: " << PoolAttrs[i].name <<
+                       " is " << strPools[i]->objectSize() <<
+                       " bytes instead of requested " <<
+                       PoolAttrs[i].obj_size << " bytes");
+        }
+
+        initialized = true;
+    }
+
+    return *strPools[type];
+}
+
+/* Find the best fit string pool type */
+static mem_type
+memFindStringSizeType(size_t net_size, bool fuzzy)
+{
+    mem_type type = MEM_NONE;
+    for (unsigned int i = 0; i < mem_str_pool_count; ++i) {
+        auto &pool = GetStrPool(i);
+        if (fuzzy && net_size < pool.objectSize()) {
+            type = static_cast<mem_type>(i);
+            break;
+        } else if (net_size == pool.objectSize()) {
+            type = static_cast<mem_type>(i);
+            break;
+        }
+    }
+
+    return type;
+}
+
 static void
 memStringStats(std::ostream &stream)
 {
@@ -111,13 +143,13 @@ memStringStats(std::ostream &stream)
     /* table body */
 
     for (i = 0; i < mem_str_pool_count; ++i) {
-        const MemAllocator *pool = StrPools[i].pool;
-        const auto plevel = pool->getMeter().inuse.currentLevel();
-        stream << std::setw(20) << std::left << pool->objectType();
+        const auto &pool = GetStrPool(i);
+        const auto plevel = pool.getMeter().inuse.currentLevel();
+        stream << std::setw(20) << std::left << pool.objectType();
         stream << std::right << "\t " << xpercentInt(plevel, StrCountMeter.currentLevel());
-        stream << "\t " << xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.currentLevel()) << "\n";
+        stream << "\t " << xpercentInt(plevel * pool.objectSize(), StrVolumeMeter.currentLevel()) << "\n";
         pooled_count += plevel;
-        pooled_volume += plevel * pool->objectSize();
+        pooled_volume += plevel * pool.objectSize();
     }
 
     /* malloc strings */
@@ -175,56 +207,49 @@ memDataInit(mem_type type, const char *name, size_t size, int, bool doZero)
 {
     assert(name && size);
 
-    if (MemPools[type] != NULL)
+    if (GetPool(type) != NULL)
         return;
 
-    MemPools[type] = memPoolCreate(name, size);
-    MemPools[type]->zeroBlocks(doZero);
+    GetPool(type) = memPoolCreate(name, size);
+    GetPool(type)->zeroBlocks(doZero);
 }
 
 /* find appropriate pool and use it (pools always init buffer with 0s) */
 void *
 memAllocate(mem_type type)
 {
-    assert(MemPools[type]);
-    return MemPools[type]->alloc();
+    assert(GetPool(type));
+    return GetPool(type)->alloc();
 }
 
 /* give memory back to the pool */
 void
 memFree(void *p, int type)
 {
-    assert(MemPools[type]);
-    MemPools[type]->freeOne(p);
+    assert(GetPool(type));
+    GetPool(type)->freeOne(p);
 }
 
 /* allocate a variable size buffer using best-fit string pool */
 void *
 memAllocString(size_t net_size, size_t * gross_size)
 {
-    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;
-            break;
-        }
+    auto type = memFindStringSizeType(net_size, true);
+    if (type != MEM_NONE) {
+        auto &pool = GetStrPool(type);
+        *gross_size = pool.objectSize();
+        assert(*gross_size >= net_size);
+        ++StrCountMeter;
+        StrVolumeMeter += *gross_size;
+        return pool.alloc();
     }
 
-    *gross_size = pool ? StrPoolsAttrs[i].obj_size : net_size;
-    assert(*gross_size >= net_size);
-    // may forget [de]allocations until MemIsInitialized
+    *gross_size = net_size;
     ++StrCountMeter;
     StrVolumeMeter += *gross_size;
-    return pool ? pool->alloc() : xcalloc(1, net_size);
+    return xcalloc(1, net_size);
 }
 
 size_t
@@ -233,7 +258,7 @@ memStringCount()
     size_t result = 0;
 
     for (int counter = 0; counter < mem_str_pool_count; ++counter)
-        result += memPoolInUseCount(StrPools[counter].pool);
+        result += GetStrPool(counter).inUseCount();
 
     return result;
 }
@@ -242,23 +267,16 @@ memStringCount()
 void
 memFreeString(size_t size, void *buf)
 {
-    MemAllocator *pool = NULL;
     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;
-            }
-        }
-    }
+    auto type = memFindStringSizeType(size, false);
+    if (type != MEM_NONE)
+        GetStrPool(type).freeOne(buf);
+    else
+        xfree(buf);
 
-    // may forget [de]allocations until MemIsInitialized
     --StrCountMeter;
     StrVolumeMeter -= size;
-    pool ? pool->freeOne(buf) : xfree(buf);
 }
 
 /* Find the best fit MEM_X_BUF type */
@@ -390,13 +408,13 @@ memConfigure(void)
     MemPools::GetInstance().setIdleLimit(new_pool_limit);
 }
 
-/* XXX make these classes do their own memory management */
-#include "HttpHdrContRange.h"
-
 void
 Mem::Init(void)
 {
-    int i;
+    /* all pools are ready to be used */
+    static bool MemIsInitialized = false;
+    if (MemIsInitialized)
+        return;
 
     /** \par
      * NOTE: Mem::Init() is called before the config file is parsed
@@ -405,9 +423,6 @@ Mem::Init(void)
      * on stderr.
      */
 
-    /** \par
-     * Set all pointers to null. */
-    memset(MemPools, '\0', sizeof(MemPools));
     /**
      * Then initialize all pools.
      * \par
@@ -424,28 +439,10 @@ Mem::Init(void)
     memDataInit(MEM_16K_BUF, "16K Buffer", 16384, 10, false);
     memDataInit(MEM_32K_BUF, "32K Buffer", 32768, 10, false);
     memDataInit(MEM_64K_BUF, "64K Buffer", 65536, 10, false);
-    memDataInit(MEM_ACL_DENY_INFO_LIST, "AclDenyInfoList",
-                sizeof(AclDenyInfoList), 0);
-    memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(AclNameList), 0);
-    memDataInit(MEM_LINK_LIST, "link_list", sizeof(link_list), 10);
-    memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10);
     memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
     memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
-    memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0);
-    memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
-    memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
-    memDataInit(MEM_CLIENT_INFO, "ClientInfo", sizeof(ClientInfo), 0);
     memDataInit(MEM_MD5_DIGEST, "MD5 digest", SQUID_MD5_DIGEST_LENGTH, 0);
-    MemPools[MEM_MD5_DIGEST]->setChunkSize(512 * 1024);
-
-    /** Lastly init the string pools. */
-    for (i = 0; i < mem_str_pool_count; ++i) {
-        StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
-        StrPools[i].pool->zeroBlocks(false);
-
-        if (StrPools[i].pool->objectSize() != StrPoolsAttrs[i].obj_size)
-            debugs(13, DBG_IMPORTANT, "Notice: " << StrPoolsAttrs[i].name << " is " << StrPools[i].pool->objectSize() << " bytes instead of requested " << StrPoolsAttrs[i].obj_size << " bytes");
-    }
+    GetPool(MEM_MD5_DIGEST)->setChunkSize(512 * 1024);
 
     MemIsInitialized = true;
 
@@ -477,13 +474,12 @@ memCheckInit(void)
 {
     mem_type t = MEM_NONE;
 
-    while (++t < MEM_DONTFREE) {
+    while (++t < MEM_MAX) {
         /*
          * If you hit this assertion, then you forgot to add a
          * memDataInit() line for type 't'.
-         * Or placed the pool type in the wrong section of the enum list.
          */
-        assert(MemPools[t]);
+        assert(GetPool(t));
     }
 }
 
@@ -505,7 +501,7 @@ memClean(void)
 int
 memInUse(mem_type type)
 {
-    return memPoolInUseCount(MemPools[type]);
+    return GetPool(type)->inUseCount();
 }
 
 /* ick */