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