#include <iomanip>
/* forward declarations */
+static void memFree32B(void *);
+static void memFree64B(void *);
+static void memFree128B(void *);
+static void memFree256B(void *);
+static void memFree512B(void *);
+static void memFree1K(void *);
static void memFree2K(void *);
static void memFree4K(void *);
static void memFree8K(void *);
/// \returns the best-fit string pool or nil
static Mem::Allocator *
-memFindStringPool(size_t net_size, bool fuzzy)
+memFindStringPool(size_t net_size)
{
for (unsigned int i = 0; i < mem_str_pool_count; ++i) {
auto &pool = GetStrPool(i);
- if (fuzzy && net_size < pool.objectSize)
- return &pool;
- if (net_size == pool.objectSize)
+ if (net_size <= pool.objectSize)
return &pool;
}
return nullptr;
stream.flush();
}
-/*
- * public routines
- */
-
/*
* we have a limit on _total_ amount of idle memory so we ignore max_pages for now.
* Will ignore repeated calls for the same pool type.
- *
- * Relies on Mem::Init() having been called beforehand.
*/
-void
+static void
memDataInit(mem_type type, const char *name, size_t size, int, bool doZero)
{
assert(name && size);
GetPool(type)->freeOne(p);
}
-/* allocate a variable size buffer using best-fit string pool */
-void *
-memAllocString(size_t net_size, size_t * gross_size)
-{
- assert(gross_size);
-
- if (const auto pool = memFindStringPool(net_size, true)) {
- *gross_size = pool->objectSize;
- assert(*gross_size >= net_size);
- ++StrCountMeter;
- StrVolumeMeter += *gross_size;
- return pool->alloc();
- }
-
- *gross_size = net_size;
- ++StrCountMeter;
- StrVolumeMeter += *gross_size;
- return xcalloc(1, net_size);
-}
-
void *
memAllocRigid(size_t net_size)
{
- // TODO: Use memAllocString() instead (after it stops zeroing memory).
+ // TODO: Use memAllocBuf() instead (after it stops zeroing memory).
- if (const auto pool = memFindStringPool(net_size, true)) {
+ if (const auto pool = memFindStringPool(net_size)) {
++StrCountMeter;
StrVolumeMeter += pool->objectSize;
return pool->alloc();
return result;
}
-/* free buffer allocated with memAllocString() */
-void
-memFreeString(size_t size, void *buf)
-{
- assert(buf);
-
- if (const auto pool = memFindStringPool(size, false))
- pool->freeOne(buf);
- else
- xfree(buf);
-
- --StrCountMeter;
- StrVolumeMeter -= size;
-}
-
void
memFreeRigid(void *buf, size_t net_size)
{
- // TODO: Use memFreeString() instead (after removing fuzzy=false pool search).
-
- if (const auto pool = memFindStringPool(net_size, true)) {
+ if (const auto pool = memFindStringPool(net_size)) {
pool->freeOne(buf);
StrVolumeMeter -= pool->objectSize;
--StrCountMeter;
mem_type type;
size_t size;
- if (net_size <= 2 * 1024) {
+ if (net_size <= 32) {
+ type = MEM_32B_BUF;
+ size = 32;
+ } else if (net_size <= 64) {
+ type = MEM_64B_BUF;
+ size = 64;
+ } else if (net_size <= 128) {
+ type = MEM_128B_BUF;
+ size = 128;
+ } else if (net_size <= 256) {
+ type = MEM_256B_BUF;
+ size = 256;
+ } else if (net_size <= 512) {
+ type = MEM_512B_BUF;
+ size = 512;
+ } else if (net_size <= 1024) {
+ type = MEM_1K_BUF;
+ size = 1024;
+ } else if (net_size <= 2 * 1024) {
type = MEM_2K_BUF;
size = 2 * 1024;
} else if (net_size <= 4 * 1024) {
/**
* Then initialize all pools.
* \par
- * Starting with generic 2kB - 64kB buffr pools, then specific object types.
+ * Starting with generic buffer pools, then specific object types.
* \par
* It does not hurt much to have a lot of pools since sizeof(MemPool) is
* small; someday we will figure out what to do with all the entries here
* that are never used or used only once; perhaps we should simply use
* malloc() for those? @?@
*/
+ memDataInit(MEM_32B_BUF, "32B Buffer", 32, 10, false);
+ memDataInit(MEM_64B_BUF, "64B Buffer", 64, 10, false);
+ memDataInit(MEM_128B_BUF, "128B Buffer", 128, 10, false);
+ memDataInit(MEM_256B_BUF, "256B Buffer", 256, 10, false);
+ memDataInit(MEM_512B_BUF, "512B Buffer", 512, 10, false);
+ memDataInit(MEM_1K_BUF, "1K Buffer", 1024, 10, false);
memDataInit(MEM_2K_BUF, "2K Buffer", 2048, 10, false);
memDataInit(MEM_4K_BUF, "4K Buffer", 4096, 10, false);
memDataInit(MEM_8K_BUF, "8K Buffer", 8192, 10, false);
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_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
- memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
- memDataInit(MEM_MD5_DIGEST, "MD5 digest", SQUID_MD5_DIGEST_LENGTH, 0);
+ // TODO: Carefully stop zeroing these objects memory and drop the doZero parameter
+ memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0, true);
+ memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0, true);
+ memDataInit(MEM_MD5_DIGEST, "MD5 digest", SQUID_MD5_DIGEST_LENGTH, 0, true);
GetPool(MEM_MD5_DIGEST)->setChunkSize(512 * 1024);
// Test that all entries are initialized
/* ick */
+void
+memFree32B(void *p)
+{
+ memFree(p, MEM_32B_BUF);
+}
+
+void
+memFree64B(void *p)
+{
+ memFree(p, MEM_64B_BUF);
+}
+
+void
+memFree128B(void *p)
+{
+ memFree(p, MEM_128B_BUF);
+}
+
+void
+memFree256B(void *p)
+{
+ memFree(p, MEM_256B_BUF);
+}
+
+void
+memFree512B(void *p)
+{
+ memFree(p, MEM_512B_BUF);
+}
+
+void
+memFree1K(void *p)
+{
+ memFree(p, MEM_1K_BUF);
+}
+
void
memFree2K(void *p)
{
{
switch (size) {
+ case 32:
+ return memFree32B;
+
+ case 64:
+ return memFree64B;
+
+ case 128:
+ return memFree128B;
+
+ case 256:
+ return memFree256B;
+
+ case 512:
+ return memFree512B;
+
+ case 1024:
+ return memFree1K;
+
case 2 * 1024:
return memFree2K;