old_api.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 13 High Level Memory Pool Management */
10 
11 #include "squid.h"
12 #include "base/PackableStream.h"
13 #include "ClientInfo.h"
14 #include "dlink.h"
15 #include "event.h"
16 #include "fs_io.h"
17 #include "icmp/net_db.h"
18 #include "md5.h"
19 #include "mem/forward.h"
20 #include "mem/Meter.h"
21 #include "mem/Pool.h"
22 #include "MemBuf.h"
23 #include "mgr/Registration.h"
24 #include "SquidConfig.h"
25 #include "SquidTime.h"
26 #include "Store.h"
27 
28 #include <iomanip>
29 
30 /* forward declarations */
31 static void memFree2K(void *);
32 static void memFree4K(void *);
33 static void memFree8K(void *);
34 static void memFree16K(void *);
35 static void memFree32K(void *);
36 static void memFree64K(void *);
37 
38 /* local prototypes */
39 static void memStringStats(std::ostream &);
40 
41 /* module locals */
42 static double xm_time = 0;
43 static double xm_deltat = 0;
44 
45 /* string pools */
46 #define mem_str_pool_count 6
47 
48 struct PoolMeta {
49  const char *name;
50  size_t obj_size;
51 };
52 
55 
58 
59 /* local routines */
60 
61 // XXX: refactor objects using these pools to use MEMPROXY classes instead
62 // then remove this function entirely
63 static MemAllocator *&
64 GetPool(size_t type)
65 {
66  static MemAllocator *pools[MEM_MAX];
67  static bool initialized = false;
68 
69  if (!initialized) {
70  memset(pools, '\0', sizeof(pools));
71  initialized = true;
72  // Mem::Init() makes use of GetPool(type) to initialize
73  // the actual pools. So must come after the flag is true
74  Mem::Init();
75  }
76 
77  return pools[type];
78 }
79 
80 static MemAllocator &
82 {
83  static MemAllocator *strPools[mem_str_pool_count];
84  static bool initialized = false;
85 
86  static const PoolMeta PoolAttrs[mem_str_pool_count] = {
87  {"Short Strings", MemAllocator::RoundedSize(36)}, /* to fit rfc1123 and similar */
88  {"Medium Strings", MemAllocator::RoundedSize(128)}, /* to fit most urls */
89  {"Long Strings", MemAllocator::RoundedSize(512)},
90  {"1KB Strings", MemAllocator::RoundedSize(1024)},
91  {"4KB Strings", MemAllocator::RoundedSize(4*1024)},
92  {"16KB Strings", MemAllocator::RoundedSize(16*1024)}
93  };
94 
95  if (!initialized) {
96  memset(strPools, '\0', sizeof(strPools));
97 
99  for (int i = 0; i < mem_str_pool_count; ++i) {
100  strPools[i] = memPoolCreate(PoolAttrs[i].name, PoolAttrs[i].obj_size);
101  strPools[i]->zeroBlocks(false);
102 
103  if (strPools[i]->objectSize() != PoolAttrs[i].obj_size)
104  debugs(13, DBG_IMPORTANT, "NOTICE: " << PoolAttrs[i].name <<
105  " is " << strPools[i]->objectSize() <<
106  " bytes instead of requested " <<
107  PoolAttrs[i].obj_size << " bytes");
108  }
109 
110  initialized = true;
111  }
112 
113  return *strPools[type];
114 }
115 
117 static MemAllocator *
118 memFindStringPool(size_t net_size, bool fuzzy)
119 {
120  for (unsigned int i = 0; i < mem_str_pool_count; ++i) {
121  auto &pool = GetStrPool(i);
122  if (fuzzy && net_size < pool.objectSize())
123  return &pool;
124  if (net_size == pool.objectSize())
125  return &pool;
126  }
127  return nullptr;
128 }
129 
130 static void
131 memStringStats(std::ostream &stream)
132 {
133  int i;
134  int pooled_count = 0;
135  size_t pooled_volume = 0;
136  /* heading */
137  stream << "String Pool\t Impact\t\t\n \t (%strings)\t (%volume)\n";
138  /* table body */
139 
140  for (i = 0; i < mem_str_pool_count; ++i) {
141  const auto &pool = GetStrPool(i);
142  const auto plevel = pool.getMeter().inuse.currentLevel();
143  stream << std::setw(20) << std::left << pool.objectType();
144  stream << std::right << "\t " << xpercentInt(plevel, StrCountMeter.currentLevel());
145  stream << "\t " << xpercentInt(plevel * pool.objectSize(), StrVolumeMeter.currentLevel()) << "\n";
146  pooled_count += plevel;
147  pooled_volume += plevel * pool.objectSize();
148  }
149 
150  /* malloc strings */
151  stream << std::setw(20) << std::left << "Other Strings";
152  stream << std::right << "\t ";
153  stream << xpercentInt(StrCountMeter.currentLevel() - pooled_count, StrCountMeter.currentLevel()) << "\t ";
154  stream << xpercentInt(StrVolumeMeter.currentLevel() - pooled_volume, StrVolumeMeter.currentLevel()) << "\n\n";
155 }
156 
157 static void
158 memBufStats(std::ostream & stream)
159 {
160  stream << "Large buffers: " <<
161  HugeBufCountMeter.currentLevel() << " (" <<
162  HugeBufVolumeMeter.currentLevel() / 1024 << " KB)\n";
163 }
164 
165 void
167 {
168  PackableStream stream(*sentry);
169  Report(stream);
170  memStringStats(stream);
171  memBufStats(stream);
172 #if WITH_VALGRIND
173  if (RUNNING_ON_VALGRIND) {
174  long int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
175  stream << "Valgrind Report:\n";
176  stream << "Type\tAmount\n";
177  debugs(13, DBG_IMPORTANT, "Asking valgrind for memleaks");
178  VALGRIND_DO_LEAK_CHECK;
179  debugs(13, DBG_IMPORTANT, "Getting valgrind statistics");
180  VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
181  stream << "Leaked\t" << leaked << "\n";
182  stream << "Dubious\t" << dubious << "\n";
183  stream << "Reachable\t" << reachable << "\n";
184  stream << "Suppressed\t" << suppressed << "\n";
185  }
186 #endif
187  stream.flush();
188 }
189 
190 /*
191  * public routines
192  */
193 
194 /*
195  * we have a limit on _total_ amount of idle memory so we ignore max_pages for now.
196  * Will ignore repeated calls for the same pool type.
197  *
198  * Relies on Mem::Init() having been called beforehand.
199  */
200 void
201 memDataInit(mem_type type, const char *name, size_t size, int, bool doZero)
202 {
203  assert(name && size);
204 
205  if (GetPool(type) != NULL)
206  return;
207 
208  GetPool(type) = memPoolCreate(name, size);
209  GetPool(type)->zeroBlocks(doZero);
210 }
211 
212 /* find appropriate pool and use it (pools always init buffer with 0s) */
213 void *
215 {
216  assert(GetPool(type));
217  return GetPool(type)->alloc();
218 }
219 
220 /* give memory back to the pool */
221 void
222 memFree(void *p, int type)
223 {
224  assert(GetPool(type));
225  GetPool(type)->freeOne(p);
226 }
227 
228 /* allocate a variable size buffer using best-fit string pool */
229 void *
230 memAllocString(size_t net_size, size_t * gross_size)
231 {
232  assert(gross_size);
233 
234  if (const auto pool = memFindStringPool(net_size, true)) {
235  *gross_size = pool->objectSize();
236  assert(*gross_size >= net_size);
237  ++StrCountMeter;
238  StrVolumeMeter += *gross_size;
239  return pool->alloc();
240  }
241 
242  *gross_size = net_size;
243  ++StrCountMeter;
244  StrVolumeMeter += *gross_size;
245  return xcalloc(1, net_size);
246 }
247 
248 void *
249 memAllocRigid(size_t net_size)
250 {
251  // TODO: Use memAllocString() instead (after it stops zeroing memory).
252 
253  if (const auto pool = memFindStringPool(net_size, true)) {
254  ++StrCountMeter;
255  StrVolumeMeter += pool->objectSize();
256  return pool->alloc();
257  }
258 
259  ++StrCountMeter;
260  StrVolumeMeter += net_size;
261  return xmalloc(net_size);
262 }
263 
264 size_t
266 {
267  size_t result = 0;
268 
269  for (int counter = 0; counter < mem_str_pool_count; ++counter)
270  result += GetStrPool(counter).inUseCount();
271 
272  return result;
273 }
274 
275 /* free buffer allocated with memAllocString() */
276 void
277 memFreeString(size_t size, void *buf)
278 {
279  assert(buf);
280 
281  if (const auto pool = memFindStringPool(size, false))
282  pool->freeOne(buf);
283  else
284  xfree(buf);
285 
286  --StrCountMeter;
287  StrVolumeMeter -= size;
288 }
289 
290 void
291 memFreeRigid(void *buf, size_t net_size)
292 {
293  // TODO: Use memFreeString() instead (after removing fuzzy=false pool search).
294 
295  if (const auto pool = memFindStringPool(net_size, true)) {
296  pool->freeOne(buf);
297  StrVolumeMeter -= pool->objectSize();
298  --StrCountMeter;
299  return;
300  }
301 
302  xfree(buf);
303  StrVolumeMeter -= net_size;
304  --StrCountMeter;
305 }
306 
307 /* Find the best fit MEM_X_BUF type */
308 static mem_type
309 memFindBufSizeType(size_t net_size, size_t * gross_size)
310 {
311  mem_type type;
312  size_t size;
313 
314  if (net_size <= 2 * 1024) {
315  type = MEM_2K_BUF;
316  size = 2 * 1024;
317  } else if (net_size <= 4 * 1024) {
318  type = MEM_4K_BUF;
319  size = 4 * 1024;
320  } else if (net_size <= 8 * 1024) {
321  type = MEM_8K_BUF;
322  size = 8 * 1024;
323  } else if (net_size <= 16 * 1024) {
324  type = MEM_16K_BUF;
325  size = 16 * 1024;
326  } else if (net_size <= 32 * 1024) {
327  type = MEM_32K_BUF;
328  size = 32 * 1024;
329  } else if (net_size <= 64 * 1024) {
330  type = MEM_64K_BUF;
331  size = 64 * 1024;
332  } else {
333  type = MEM_NONE;
334  size = net_size;
335  }
336 
337  if (gross_size)
338  *gross_size = size;
339 
340  return type;
341 }
342 
343 /* allocate a variable size buffer using best-fit pool */
344 void *
345 memAllocBuf(size_t net_size, size_t * gross_size)
346 {
347  mem_type type = memFindBufSizeType(net_size, gross_size);
348 
349  if (type != MEM_NONE)
350  return memAllocate(type);
351  else {
353  HugeBufVolumeMeter += *gross_size;
354  return xcalloc(1, net_size);
355  }
356 }
357 
358 /* resize a variable sized buffer using best-fit pool */
359 void *
360 memReallocBuf(void *oldbuf, size_t net_size, size_t * gross_size)
361 {
362  /* XXX This can be optimized on very large buffers to use realloc() */
363  /* TODO: if the existing gross size is >= new gross size, do nothing */
364  size_t new_gross_size;
365  void *newbuf = memAllocBuf(net_size, &new_gross_size);
366 
367  if (oldbuf) {
368  size_t data_size = *gross_size;
369 
370  if (data_size > net_size)
371  data_size = net_size;
372 
373  memcpy(newbuf, oldbuf, data_size);
374 
375  memFreeBuf(*gross_size, oldbuf);
376  }
377 
378  *gross_size = new_gross_size;
379  return newbuf;
380 }
381 
382 /* free buffer allocated with memAllocBuf() */
383 void
384 memFreeBuf(size_t size, void *buf)
385 {
387 
388  if (type != MEM_NONE)
389  memFree(buf, type);
390  else {
391  xfree(buf);
394  }
395 }
396 
397 static double clean_interval = 15.0; /* time to live of idle chunk before release */
398 
399 void
401 {
402  MemPools::GetInstance().clean(static_cast<time_t>(clean_interval));
403  eventAdd("memPoolCleanIdlePools", CleanIdlePools, NULL, clean_interval, 1);
404 }
405 
406 void
408 {
409  int64_t new_pool_limit;
410 
412  if (!Config.onoff.mem_pools)
413  new_pool_limit = 0;
414  else if (Config.MemPools.limit > 0)
415  new_pool_limit = Config.MemPools.limit;
416  else {
417  if (Config.MemPools.limit == 0)
418  debugs(13, DBG_IMPORTANT, "memory_pools_limit 0 has been chagned to memory_pools_limit none. Please update your config");
419  new_pool_limit = -1;
420  }
421 
422  MemPools::GetInstance().setIdleLimit(new_pool_limit);
423 }
424 
425 void
427 {
428  /* all pools are ready to be used */
429  static bool MemIsInitialized = false;
430  if (MemIsInitialized)
431  return;
432 
450  memDataInit(MEM_2K_BUF, "2K Buffer", 2048, 10, false);
451  memDataInit(MEM_4K_BUF, "4K Buffer", 4096, 10, false);
452  memDataInit(MEM_8K_BUF, "8K Buffer", 8192, 10, false);
453  memDataInit(MEM_16K_BUF, "16K Buffer", 16384, 10, false);
454  memDataInit(MEM_32K_BUF, "32K Buffer", 32768, 10, false);
455  memDataInit(MEM_64K_BUF, "64K Buffer", 65536, 10, false);
456  memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
457  memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
459  GetPool(MEM_MD5_DIGEST)->setChunkSize(512 * 1024);
460 
461  MemIsInitialized = true;
462 
463  // finally register with the cache manager
464  Mgr::RegisterAction("mem", "Memory Utilization", Mem::Stats, 0, 1);
465 }
466 
467 void
469 {
470  debugs(13, 3, "Memory pools are '" <<
471  (Config.onoff.mem_pools ? "on" : "off") << "'; limit: " <<
472  std::setprecision(3) << toMB(MemPools::GetInstance().idleLimit()) <<
473  " MB");
474 }
475 
476 static mem_type &
478 {
479  int tmp = (int)aMem;
480  aMem = (mem_type)(++tmp);
481  return aMem;
482 }
483 
484 /*
485  * Test that all entries are initialized
486  */
487 void
489 {
490  mem_type t = MEM_NONE;
491 
492  while (++t < MEM_MAX) {
493  /*
494  * If you hit this assertion, then you forgot to add a
495  * memDataInit() line for type 't'.
496  */
497  assert(GetPool(t));
498  }
499 }
500 
501 void
502 memClean(void)
503 {
505  if (Config.MemPools.limit > 0) // do not reset if disabled or same
509 
510  if (stats.tot_items_inuse)
511  debugs(13, 2, "memCleanModule: " << stats.tot_items_inuse <<
512  " items in " << stats.tot_chunks_inuse << " chunks and " <<
513  stats.tot_pools_inuse << " pools are left dirty");
514 }
515 
516 int
518 {
519  return GetPool(type)->inUseCount();
520 }
521 
522 /* ick */
523 
524 void
525 memFree2K(void *p)
526 {
527  memFree(p, MEM_2K_BUF);
528 }
529 
530 void
531 memFree4K(void *p)
532 {
533  memFree(p, MEM_4K_BUF);
534 }
535 
536 void
537 memFree8K(void *p)
538 {
539  memFree(p, MEM_8K_BUF);
540 }
541 
542 void
543 memFree16K(void *p)
544 {
545  memFree(p, MEM_16K_BUF);
546 }
547 
548 void
549 memFree32K(void *p)
550 {
551  memFree(p, MEM_32K_BUF);
552 }
553 
554 void
555 memFree64K(void *p)
556 {
557  memFree(p, MEM_64K_BUF);
558 }
559 
560 static void
561 cxx_xfree(void * ptr)
562 {
563  xfree(ptr);
564 }
565 
566 FREE *
568 {
569  switch (size) {
570 
571  case 2 * 1024:
572  return memFree2K;
573 
574  case 4 * 1024:
575  return memFree4K;
576 
577  case 8 * 1024:
578  return memFree8K;
579 
580  case 16 * 1024:
581  return memFree16K;
582 
583  case 32 * 1024:
584  return memFree32K;
585 
586  case 64 * 1024:
587  return memFree64K;
588 
589  default:
592  return cxx_xfree;
593  }
594 }
595 
596 /* MemPoolMeter */
597 
598 void
599 Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std::ostream &stream)
600 {
601  int excess = 0;
602  int needed = 0;
603  MemPoolMeter *pm = mp_st->meter;
604  const char *delim = "\t ";
605 
606  stream.setf(std::ios_base::fixed);
607  stream << std::setw(20) << std::left << mp_st->label << delim;
608  stream << std::setw(4) << std::right << mp_st->obj_size << delim;
609 
610  /* Chunks */
611  if (mp_st->chunk_capacity) {
612  stream << std::setw(4) << toKB(mp_st->obj_size * mp_st->chunk_capacity) << delim;
613  stream << std::setw(4) << mp_st->chunk_capacity << delim;
614 
615  needed = mp_st->items_inuse / mp_st->chunk_capacity;
616 
617  if (mp_st->items_inuse % mp_st->chunk_capacity)
618  ++needed;
619 
620  excess = mp_st->chunks_inuse - needed;
621 
622  stream << std::setw(4) << mp_st->chunks_alloc << delim;
623  stream << std::setw(4) << mp_st->chunks_inuse << delim;
624  stream << std::setw(4) << mp_st->chunks_free << delim;
625  stream << std::setw(4) << mp_st->chunks_partial << delim;
626  stream << std::setprecision(3) << xpercent(excess, needed) << delim;
627  } else {
628  stream << delim;
629  stream << delim;
630  stream << delim;
631  stream << delim;
632  stream << delim;
633  stream << delim;
634  stream << delim;
635  }
636  /*
637  * Fragmentation calculation:
638  * needed = inuse.currentLevel() / chunk_capacity
639  * excess = used - needed
640  * fragmentation = excess / needed * 100%
641  *
642  * Fragm = (alloced - (inuse / obj_ch) ) / alloced
643  */
644  /* allocated */
645  stream << mp_st->items_alloc << delim;
646  stream << toKB(mp_st->obj_size * pm->alloc.currentLevel()) << delim;
647  stream << toKB(mp_st->obj_size * pm->alloc.peak()) << delim;
648  stream << std::setprecision(2) << ((squid_curtime - pm->alloc.peakTime()) / 3600.) << delim;
649  stream << std::setprecision(3) << xpercent(mp_st->obj_size * pm->alloc.currentLevel(), AllMeter->alloc.currentLevel()) << delim;
650  /* in use */
651  stream << mp_st->items_inuse << delim;
652  stream << toKB(mp_st->obj_size * pm->inuse.currentLevel()) << delim;
653  stream << toKB(mp_st->obj_size * pm->inuse.peak()) << delim;
654  stream << std::setprecision(2) << ((squid_curtime - pm->inuse.peakTime()) / 3600.) << delim;
655  stream << std::setprecision(3) << xpercent(pm->inuse.currentLevel(), pm->alloc.currentLevel()) << delim;
656  /* idle */
657  stream << mp_st->items_idle << delim;
658  stream << toKB(mp_st->obj_size * pm->idle.currentLevel()) << delim;
659  stream << toKB(mp_st->obj_size * pm->idle.peak()) << delim;
660  /* saved */
661  stream << (int)pm->gb_saved.count << delim;
662  stream << std::setprecision(3) << xpercent(pm->gb_saved.count, AllMeter->gb_allocated.count) << delim;
663  stream << std::setprecision(3) << xpercent(pm->gb_saved.bytes, AllMeter->gb_allocated.bytes) << delim;
664  stream << std::setprecision(3) << xdiv(pm->gb_allocated.count - pm->gb_oallocated.count, xm_deltat) << "\n";
666 }
667 
668 static int
669 MemPoolReportSorter(const void *a, const void *b)
670 {
671  const MemPoolStats *A = (MemPoolStats *) a;
672  const MemPoolStats *B = (MemPoolStats *) b;
673 
674  // use this to sort on %Total Allocated
675  //
676  double pa = (double) A->obj_size * A->meter->alloc.currentLevel();
677  double pb = (double) B->obj_size * B->meter->alloc.currentLevel();
678 
679  if (pa > pb)
680  return -1;
681 
682  if (pb > pa)
683  return 1;
684 
685  return 0;
686 }
687 
688 void
689 Mem::Report(std::ostream &stream)
690 {
691  static char buf[64];
692  static MemPoolStats mp_stats;
693  static MemPoolGlobalStats mp_total;
694  int not_used = 0;
695  MemPoolIterator *iter;
696  MemAllocator *pool;
697 
698  /* caption */
699  stream << "Current memory usage:\n";
700  /* heading */
701  stream << "Pool\t Obj Size\t"
702  "Chunks\t\t\t\t\t\t\t"
703  "Allocated\t\t\t\t\t"
704  "In Use\t\t\t\t\t"
705  "Idle\t\t\t"
706  "Allocations Saved\t\t\t"
707  "Rate\t"
708  "\n"
709  " \t (bytes)\t"
710  "KB/ch\t obj/ch\t"
711  "(#)\t used\t free\t part\t %Frag\t "
712  "(#)\t (KB)\t high (KB)\t high (hrs)\t %Tot\t"
713  "(#)\t (KB)\t high (KB)\t high (hrs)\t %alloc\t"
714  "(#)\t (KB)\t high (KB)\t"
715  "(#)\t %cnt\t %vol\t"
716  "(#)/sec\t"
717  "\n";
720 
721  /* Get stats for Totals report line */
722  memPoolGetGlobalStats(&mp_total);
723 
724  MemPoolStats *sortme = (MemPoolStats *) xcalloc(mp_total.tot_pools_alloc,sizeof(*sortme));
725  int npools = 0;
726 
727  /* main table */
728  iter = memPoolIterate();
729 
730  while ((pool = memPoolIterateNext(iter))) {
731  pool->getStats(&mp_stats);
732 
733  if (!mp_stats.pool) /* pool destroyed */
734  continue;
735 
736  if (mp_stats.pool->getMeter().gb_allocated.count > 0) {
737  /* this pool has been used */
738  sortme[npools] = mp_stats;
739  ++npools;
740  } else {
741  ++not_used;
742  }
743  }
744 
745  memPoolIterateDone(&iter);
746 
747  qsort(sortme, npools, sizeof(*sortme), MemPoolReportSorter);
748 
749  for (int i = 0; i< npools; ++i) {
750  PoolReport(&sortme[i], mp_total.TheMeter, stream);
751  }
752 
753  xfree(sortme);
754 
755  mp_stats.pool = NULL;
756  mp_stats.label = "Total";
757  mp_stats.meter = mp_total.TheMeter;
758  mp_stats.obj_size = 1;
759  mp_stats.chunk_capacity = 0;
760  mp_stats.chunk_size = 0;
761  mp_stats.chunks_alloc = mp_total.tot_chunks_alloc;
762  mp_stats.chunks_inuse = mp_total.tot_chunks_inuse;
763  mp_stats.chunks_partial = mp_total.tot_chunks_partial;
764  mp_stats.chunks_free = mp_total.tot_chunks_free;
765  mp_stats.items_alloc = mp_total.tot_items_alloc;
766  mp_stats.items_inuse = mp_total.tot_items_inuse;
767  mp_stats.items_idle = mp_total.tot_items_idle;
768  mp_stats.overhead = mp_total.tot_overhead;
769 
770  PoolReport(&mp_stats, mp_total.TheMeter, stream);
771 
772  /* Cumulative */
773  stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.TheMeter->gb_allocated.bytes) << "\n";
774  /* overhead */
775  stream << "Current overhead: " << mp_total.tot_overhead << " bytes (" <<
776  std::setprecision(3) << xpercent(mp_total.tot_overhead, mp_total.TheMeter->inuse.currentLevel()) << "%)\n";
777  /* limits */
778  if (mp_total.mem_idle_limit >= 0)
779  stream << "Idle pool limit: " << std::setprecision(2) << toMB(mp_total.mem_idle_limit) << " MB\n";
780  /* limits */
781  stream << "Total Pools created: " << mp_total.tot_pools_alloc << "\n";
782  stream << "Pools ever used: " << mp_total.tot_pools_alloc - not_used << " (shown above)\n";
783  stream << "Currently in use: " << mp_total.tot_pools_inuse << "\n";
784 }
785 
@ MEM_DREAD_CTRL
Definition: forward.h:47
void clean(time_t maxage)
Definition: Pool.cc:224
SQUIDCEXTERN double xpercent(double part, double whole)
Definition: util.c:54
static mem_type & operator++(mem_type &aMem)
Definition: old_api.cc:477
int tot_pools_inuse
Definition: Pool.h:307
class Ping::pingStats_ stats
Mem::Meter inuse
Definition: Pool.h:99
void * xcalloc(size_t n, size_t sz)
Definition: xalloc.cc:72
MemPoolMeter * meter
Definition: Pool.h:284
int items_alloc
Definition: Pool.h:294
#define xmalloc
@ MEM_64K_BUF
Definition: forward.h:46
void memCheckInit(void)
Definition: old_api.cc:488
time_t peakTime() const
Definition: Meter.h:30
static double clean_interval
Definition: old_api.cc:397
int chunks_alloc
Definition: Pool.h:289
void FREE(void *)
Definition: forward.h:36
void * memAllocate(mem_type type)
Allocate one element from the typed pool.
Definition: old_api.cc:214
static void memFree16K(void *)
Definition: old_api.cc:543
void memPoolIterateDone(MemPoolIterator **iter)
Definition: Pool.cc:47
int tot_chunks_alloc
Definition: Pool.h:310
static void memFree64K(void *)
Definition: old_api.cc:555
void memFreeBuf(size_t size, void *buf)
Definition: old_api.cc:384
int items_idle
Definition: Pool.h:296
int obj_size
Definition: Pool.h:285
static Mem::Meter StrVolumeMeter
Definition: old_api.cc:54
mem_type
Types of memory pool which do not yet use MEMPROXY_CLASS() API.
Definition: forward.h:39
void * memAllocString(size_t net_size, size_t *gross_size)
Definition: old_api.cc:230
int tot_items_idle
Definition: Pool.h:317
@ MEM_MD5_DIGEST
Definition: forward.h:49
int memPoolGetGlobalStats(MemPoolGlobalStats *stats)
Definition: Pool.cc:250
MemAllocator * pool
Definition: Pool.h:282
void * memAllocBuf(size_t net_size, size_t *gross_size)
Definition: old_api.cc:345
int chunks_inuse
Definition: Pool.h:290
int type
Definition: errorpage.cc:153
static void cxx_xfree(void *ptr)
Definition: old_api.cc:561
SQUIDCEXTERN const char * double_to_str(char *buf, int buf_size, double value)
Definition: util.c:109
FREE * memFreeBufFunc(size_t size)
Definition: old_api.cc:567
static Mem::Meter StrCountMeter
Definition: old_api.cc:53
MemPoolMeter * TheMeter
Definition: Pool.h:304
static void memFree32K(void *)
Definition: old_api.cc:549
MemImplementingAllocator * memPoolIterateNext(MemPoolIterator *iter)
Definition: Pool.cc:55
void memFree(void *p, int type)
Free a element allocated by memAllocate()
Definition: old_api.cc:222
ssize_t peak() const
Definition: Meter.h:29
#define DBG_IMPORTANT
Definition: Debug.h:41
int items_inuse
Definition: Pool.h:295
int chunk_capacity
Definition: Pool.h:286
ssize_t currentLevel() const
Definition: Meter.h:28
static mem_type memFindBufSizeType(size_t net_size, size_t *gross_size)
Definition: old_api.cc:309
size_t obj_size
Definition: old_api.cc:50
void memFreeString(size_t size, void *buf)
Definition: old_api.cc:277
int tot_chunks_free
Definition: Pool.h:313
void memClean(void)
Main cleanup handler.
Definition: old_api.cc:502
static MemAllocator *& GetPool(size_t type)
Definition: old_api.cc:64
int overhead
Definition: Pool.h:298
void memConfigure(void)
Definition: old_api.cc:407
int chunks_free
Definition: Pool.h:292
int memInUse(mem_type type)
Definition: old_api.cc:517
static Mem::Meter HugeBufVolumeMeter
Definition: old_api.cc:57
void * memReallocBuf(void *oldbuf, size_t net_size, size_t *gross_size)
Definition: old_api.cc:360
int chunk_size
Definition: Pool.h:287
#define SQUID_MD5_DIGEST_LENGTH
Definition: md5.h:66
virtual MemPoolMeter const & getMeter() const =0
MemPoolIterator * memPoolIterate(void)
Definition: Pool.cc:40
void Stats(StoreEntry *)
Definition: old_api.cc:166
#define toKB(size)
Definition: Pool.h:52
virtual void freeOne(void *)=0
int size
Definition: ModDevPoll.cc:77
#define NULL
Definition: types.h:166
void * memAllocRigid(size_t net_size)
Definition: old_api.cc:249
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:123
static MemAllocator * memFindStringPool(size_t net_size, bool fuzzy)
Definition: old_api.cc:118
static void memFree2K(void *)
Definition: old_api.cc:525
static uint32 A
Definition: md4.c:43
void setIdleLimit(ssize_t new_idle_limit)
Definition: Pool.cc:69
void Report()
Definition: old_api.cc:468
static double xm_time
Definition: old_api.cc:42
static void memStringStats(std::ostream &)
Definition: old_api.cc:131
static size_t RoundedSize(size_t minSize)
Definition: Pool.cc:293
int tot_items_alloc
Definition: Pool.h:315
#define assert(EX)
Definition: assert.h:19
void EVH void double
Definition: stub_event.cc:16
mgb_t gb_allocated
Definition: Pool.h:103
virtual void setChunkSize(size_t)
Definition: Pool.h:218
static double xm_deltat
Definition: old_api.cc:43
int64_t limit
Definition: SquidConfig.h:448
#define toMB(size)
Definition: Pool.h:50
static void memBufStats(std::ostream &stream)
Definition: old_api.cc:158
time_t squid_curtime
Definition: stub_time.cc:17
@ MEM_NONE
Definition: forward.h:40
#define xfree
const char * label
Definition: Pool.h:283
double bytes
Definition: Pool.h:85
int tot_pools_alloc
Definition: Pool.h:306
#define mem_str_pool_count
Definition: old_api.cc:46
void zeroBlocks(bool doIt)
Definition: Pool.h:205
int tot_chunks_inuse
Definition: Pool.h:311
const char * name
Definition: old_api.cc:49
struct SquidConfig::@116 MemPools
@ MEM_16K_BUF
Definition: forward.h:44
@ MEM_32K_BUF
Definition: forward.h:45
@ MEM_4K_BUF
Definition: forward.h:42
mgb_t gb_oallocated
Definition: Pool.h:104
virtual void * alloc()=0
size_t memStringCount()
Definition: old_api.cc:265
@ MEM_8K_BUF
Definition: forward.h:43
#define memPoolCreate
Definition: Pool.h:325
struct SquidConfig::@111 onoff
virtual int getStats(MemPoolStats *stats, int accumulate=0)=0
int inUseCount()
Definition: Pool.cc:113
void PoolReport(const MemPoolStats *mp_st, const MemPoolMeter *AllMeter, std::ostream &)
Definition: old_api.cc:599
void Init()
Definition: old_api.cc:426
static MemPools & GetInstance()
Definition: Pool.cc:30
Definition: fs_io.h:35
@ MEM_MAX
Definition: forward.h:50
void CleanIdlePools(void *unused)
Definition: old_api.cc:400
void memDataInit(mem_type type, const char *name, size_t size, int, bool doZero)
Definition: old_api.cc:201
SQUIDCEXTERN double xdiv(double nom, double denom)
Definition: util.c:72
Mem::Meter alloc
Definition: Pool.h:98
static void memFree8K(void *)
Definition: old_api.cc:537
int chunks_partial
Definition: Pool.h:291
int tot_items_inuse
Definition: Pool.h:316
static int MemPoolReportSorter(const void *a, const void *b)
Definition: old_api.cc:669
@ MEM_DWRITE_Q
Definition: forward.h:48
static Mem::Meter HugeBufCountMeter
Definition: old_api.cc:56
static uint32 B
Definition: md4.c:43
void memFreeRigid(void *buf, size_t net_size)
Definition: old_api.cc:291
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
Definition: Registration.cc:16
int tot_chunks_partial
Definition: Pool.h:312
@ MEM_2K_BUF
Definition: forward.h:41
mgb_t gb_saved
Definition: Pool.h:107
static void memFree4K(void *)
Definition: old_api.cc:531
SQUIDCEXTERN int xpercentInt(double part, double whole)
Definition: util.c:60
ssize_t mem_idle_limit
Definition: Pool.h:320
double current_dtime
Definition: stub_time.cc:16
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
Definition: event.cc:109
double count
Definition: Pool.h:84
static MemAllocator & GetStrPool(size_t type)
Definition: old_api.cc:81
class SquidConfig Config
Definition: SquidConfig.cc:12
int unsigned int
Definition: stub_fd.cc:19
Mem::Meter idle
Definition: Pool.h:100

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors