]> git.ipfire.org Git - thirdparty/squid.git/blame - src/mem.cc
Updated copyright
[thirdparty/squid.git] / src / mem.cc
CommitLineData
acf5589a 1
2/*
2b6662ba 3 * $Id: mem.cc,v 1.54 2001/01/12 00:37:19 wessels Exp $
acf5589a 4 *
7021844c 5 * DEBUG: section 13 High Level Memory Pool Management
acf5589a 6 * AUTHOR: Harvest Derived
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
acf5589a 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
acf5589a 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
acf5589a 34 */
35
36#include "squid.h"
37
7021844c 38/* module globals */
acf5589a 39
7021844c 40static MemPool *MemPools[MEM_MAX];
acf5589a 41
9fe7e747 42/* string pools */
43#define mem_str_pool_count 3
ec878047 44static const struct {
45 const char *name;
9fe7e747 46 size_t obj_size;
ec878047 47} StrPoolsAttrs[mem_str_pool_count] = {
4b4cd312 48
ec878047 49 {
50 "Short Strings", 36,
51 }, /* to fit rfc1123 and similar */
52 {
53 "Medium Strings", 128,
54 }, /* to fit most urls */
55 {
56 "Long Strings", 512
57 } /* other */
9fe7e747 58};
ec878047 59static struct {
60 MemPool *pool;
61} StrPools[mem_str_pool_count];
9fe7e747 62static MemMeter StrCountMeter;
63static MemMeter StrVolumeMeter;
64
65
66/* local routines */
67
9fe7e747 68static void
69memStringStats(StoreEntry * sentry)
70{
71 const char *pfmt = "%-20s\t %d\t %d\n";
72 int i;
73 int pooled_count = 0;
74 size_t pooled_volume = 0;
75 /* heading */
ec878047 76 storeAppendPrintf(sentry,
9fe7e747 77 "String Pool\t Impact\t\t\n"
78 " \t (%%strings)\t (%%volume)\n");
79 /* table body */
80 for (i = 0; i < mem_str_pool_count; i++) {
81 const MemPool *pool = StrPools[i].pool;
82 const int plevel = pool->meter.inuse.level;
ec878047 83 storeAppendPrintf(sentry, pfmt,
9fe7e747 84 pool->label,
85 xpercentInt(plevel, StrCountMeter.level),
ec878047 86 xpercentInt(plevel * pool->obj_size, StrVolumeMeter.level));
9fe7e747 87 pooled_count += plevel;
ec878047 88 pooled_volume += plevel * pool->obj_size;
9fe7e747 89 }
90 /* malloc strings */
91 storeAppendPrintf(sentry, pfmt,
92 "Other Strings",
ec878047 93 xpercentInt(StrCountMeter.level - pooled_count, StrCountMeter.level),
94 xpercentInt(StrVolumeMeter.level - pooled_volume, StrVolumeMeter.level));
9fe7e747 95}
96
acf5589a 97static void
7021844c 98memStats(StoreEntry * sentry)
acf5589a 99{
7021844c 100 storeBuffer(sentry);
b4832aa9 101 memReport(sentry);
9fe7e747 102 memStringStats(sentry);
7021844c 103 storeBufferFlush(sentry);
acf5589a 104}
105
7021844c 106
acf5589a 107/*
9fe7e747 108 * public routines
acf5589a 109 */
110
58a39dc9 111/*
112 * we have a limit on _total_ amount of idle memory so we ignore
113 * max_pages for now
114 */
115void
116memDataInit(mem_type type, const char *name, size_t size, int max_pages_notused)
117{
118 assert(name && size);
119 MemPools[type] = memPoolCreate(name, size);
120}
121
9fe7e747 122
7021844c 123/* find appropriate pool and use it (pools always init buffer with 0s) */
acf5589a 124void *
7021844c 125memAllocate(mem_type type)
acf5589a 126{
7021844c 127 return memPoolAlloc(MemPools[type]);
acf5589a 128}
129
db1cd23c 130/* give memory back to the pool */
acf5589a 131void
db1cd23c 132memFree(void *p, int type)
acf5589a 133{
7021844c 134 memPoolFree(MemPools[type], p);
acf5589a 135}
136
9fe7e747 137/* allocate a variable size buffer using best-fit pool */
138void *
ec878047 139memAllocBuf(size_t net_size, size_t * gross_size)
9fe7e747 140{
141 int i;
142 MemPool *pool = NULL;
143 assert(gross_size);
144 for (i = 0; i < mem_str_pool_count; i++) {
145 if (net_size <= StrPoolsAttrs[i].obj_size) {
ec878047 146 pool = StrPools[i].pool;
9fe7e747 147 break;
148 }
149 }
150 *gross_size = pool ? pool->obj_size : net_size;
151 assert(*gross_size >= net_size);
152 memMeterInc(StrCountMeter);
153 memMeterAdd(StrVolumeMeter, *gross_size);
154 return pool ? memPoolAlloc(pool) : xcalloc(1, net_size);
155}
156
157/* free buffer allocated with memAllocBuf() */
158void
159memFreeBuf(size_t size, void *buf)
160{
161 int i;
162 MemPool *pool = NULL;
163 assert(size && buf);
164 for (i = 0; i < mem_str_pool_count; i++) {
165 if (size <= StrPoolsAttrs[i].obj_size) {
166 assert(size == StrPoolsAttrs[i].obj_size);
167 pool = StrPools[i].pool;
168 break;
169 }
170 }
171 memMeterDec(StrCountMeter);
172 memMeterDel(StrVolumeMeter, size);
173 pool ? memPoolFree(pool, buf) : xfree(buf);
174}
175
acf5589a 176void
177memInit(void)
178{
9fe7e747 179 int i;
7021844c 180 memInitModule();
181 /* set all pointers to null */
182 memset(MemPools, '\0', sizeof(MemPools));
183 /*
184 * it does not hurt much to have a lot of pools since sizeof(MemPool) is
185 * small; someday we will figure out what to do with all the entries here
186 * that are never used or used only once; perhaps we should simply use
187 * malloc() for those? @?@
188 */
137ee196 189 memDataInit(MEM_2K_BUF, "2K Buffer", 2048, 10);
acf5589a 190 memDataInit(MEM_4K_BUF, "4K Buffer", 4096, 10);
191 memDataInit(MEM_8K_BUF, "8K Buffer", 8192, 10);
58cd5bbd 192 memDataInit(MEM_16K_BUF, "16K Buffer", 16384, 10);
193 memDataInit(MEM_32K_BUF, "32K Buffer", 32768, 10);
194 memDataInit(MEM_64K_BUF, "64K Buffer", 65536, 10);
cc27d775 195 memDataInit(MEM_CLIENT_SOCK_BUF, "Client Socket Buffer", CLIENT_SOCK_SZ, 0);
acf5589a 196 memDataInit(MEM_ACCESSLOGENTRY, "AccessLogEntry",
197 sizeof(AccessLogEntry), 10);
198 memDataInit(MEM_ACL, "acl", sizeof(acl), 0);
199 memDataInit(MEM_ACLCHECK_T, "aclCheck_t", sizeof(aclCheck_t), 0);
200 memDataInit(MEM_ACL_ACCESS, "acl_access", sizeof(acl_access), 0);
201 memDataInit(MEM_ACL_DENY_INFO_LIST, "acl_deny_info_list",
202 sizeof(acl_deny_info_list), 0);
203 memDataInit(MEM_ACL_IP_DATA, "acl_ip_data", sizeof(acl_ip_data), 0);
204 memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0);
205 memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0);
206 memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0);
94439e4e 207 memDataInit(MEM_AUTH_USER_T, "auth_user_t",
208 sizeof(auth_user_t), 0);
209 memDataInit(MEM_AUTH_USER_HASH, "auth_user_hash_pointer",
210 sizeof(auth_user_hash_pointer), 0);
211 memDataInit(MEM_ACL_PROXY_AUTH_MATCH, "acl_proxy_auth_match_cache",
212 sizeof(acl_proxy_auth_match_cache), 0);
a72fdaa7 213 memDataInit(MEM_ACL_USER_DATA, "acl_user_data",
cf86841e 214 sizeof(acl_user_data), 0);
acf5589a 215 memDataInit(MEM_CACHEMGR_PASSWD, "cachemgr_passwd",
216 sizeof(cachemgr_passwd), 0);
c68e9c6b 217#if USE_CACHE_DIGESTS
26c2ce6f 218 memDataInit(MEM_CACHE_DIGEST, "CacheDigest", sizeof(CacheDigest), 0);
c68e9c6b 219#endif
acf5589a 220 memDataInit(MEM_CLIENTHTTPREQUEST, "clientHttpRequest",
221 sizeof(clientHttpRequest), 0);
222 memDataInit(MEM_CLOSE_HANDLER, "close_handler", sizeof(close_handler), 0);
223 memDataInit(MEM_COMMWRITESTATEDATA, "CommWriteStateData",
224 sizeof(CommWriteStateData), 0);
225 memDataInit(MEM_CONNSTATEDATA, "ConnStateData", sizeof(ConnStateData), 0);
e13ee7ad 226#if USE_CACHE_DIGESTS
227 memDataInit(MEM_DIGEST_FETCH_STATE, "DigestFetchState", sizeof(DigestFetchState), 0);
228#endif
58cd5bbd 229 memDataInit(MEM_LINK_LIST, "link_list", sizeof(link_list), 10);
acf5589a 230 memDataInit(MEM_DLINK_LIST, "dlink_list", sizeof(dlink_list), 10);
231 memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10);
232 memDataInit(MEM_DNSSERVER_T, "dnsserver_t", sizeof(dnsserver_t), 0);
233 memDataInit(MEM_DNSSTATDATA, "dnsStatData", sizeof(dnsStatData), 0);
234 memDataInit(MEM_DOMAIN_PING, "domain_ping", sizeof(domain_ping), 0);
235 memDataInit(MEM_DOMAIN_TYPE, "domain_type", sizeof(domain_type), 0);
236 memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
237 memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
238 memDataInit(MEM_ERRORSTATE, "ErrorState", sizeof(ErrorState), 0);
239 memDataInit(MEM_FILEMAP, "fileMap", sizeof(fileMap), 0);
798b0889 240 memDataInit(MEM_FWD_STATE, "FwdState", sizeof(FwdState), 0);
241 memDataInit(MEM_FWD_SERVER, "FwdServer", sizeof(FwdServer), 0);
acf5589a 242 memDataInit(MEM_HASH_LINK, "hash_link", sizeof(hash_link), 0);
243 memDataInit(MEM_HASH_TABLE, "hash_table", sizeof(hash_table), 0);
244 memDataInit(MEM_HIERARCHYLOGENTRY, "HierarchyLogEntry",
245 sizeof(HierarchyLogEntry), 0);
4cc73db3 246 memDataInit(MEM_HTTP_STATE_DATA, "HttpStateData", sizeof(HttpStateData), 0);
d8b249ef 247 memDataInit(MEM_HTTP_REPLY, "HttpReply", sizeof(HttpReply), 0);
248 memDataInit(MEM_HTTP_HDR_ENTRY, "HttpHeaderEntry", sizeof(HttpHeaderEntry), 0);
7faf2bdb 249 memDataInit(MEM_HTTP_HDR_CC, "HttpHdrCc", sizeof(HttpHdrCc), 0);
eed12adc 250 memDataInit(MEM_HTTP_HDR_RANGE_SPEC, "HttpHdrRangeSpec", sizeof(HttpHdrRangeSpec), 0);
251 memDataInit(MEM_HTTP_HDR_RANGE, "HttpHdrRange", sizeof(HttpHdrRange), 0);
d76fcfa7 252 memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0);
acf5589a 253 memDataInit(MEM_ICPUDPDATA, "icpUdpData", sizeof(icpUdpData), 0);
254 memDataInit(MEM_ICP_COMMON_T, "icp_common_t", sizeof(icp_common_t), 0);
b4e7f82d 255 memDataInit(MEM_ICP_PING_DATA, "ping_data", sizeof(ping_data), 0);
acf5589a 256 memDataInit(MEM_INTLIST, "intlist", sizeof(intlist), 0);
257 memDataInit(MEM_IOSTATS, "iostats", sizeof(iostats), 0);
acf5589a 258 memDataInit(MEM_MEMOBJECT, "MemObject", sizeof(MemObject),
259 Squid_MaxFD >> 3);
acf5589a 260 memDataInit(MEM_MEM_NODE, "mem_node", sizeof(mem_node), 0);
acf5589a 261 memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
262 memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
263 memDataInit(MEM_NET_DB_PEER, "net_db_peer", sizeof(net_db_peer), 0);
e13ee7ad 264 memDataInit(MEM_PEER, "peer", sizeof(peer), 0);
c68e9c6b 265#if USE_CACHE_DIGESTS
e13ee7ad 266 memDataInit(MEM_PEER_DIGEST, "PeerDigest", sizeof(PeerDigest), 0);
e42d5181 267 memDataInit(MEM_DIGEST_FETCH_STATE, "DigestFetchState", sizeof(DigestFetchState), 0);
c68e9c6b 268#endif
6b53c392 269#if USE_ICMP
acf5589a 270 memDataInit(MEM_PINGERECHODATA, "pingerEchoData",
271 sizeof(pingerEchoData), 0);
272 memDataInit(MEM_PINGERREPLYDATA, "pingerReplyData",
273 sizeof(pingerReplyData), 0);
6b53c392 274#endif
acf5589a 275 memDataInit(MEM_PS_STATE, "ps_state", sizeof(ps_state), 0);
276 memDataInit(MEM_REFRESH_T, "refresh_t", sizeof(refresh_t), 0);
277 memDataInit(MEM_RELIST, "relist", sizeof(relist), 0);
278 memDataInit(MEM_REQUEST_T, "request_t", sizeof(request_t),
279 Squid_MaxFD >> 3);
acf5589a 280 memDataInit(MEM_SQUIDCONFIG, "SquidConfig", sizeof(SquidConfig), 0);
281 memDataInit(MEM_SQUIDCONFIG2, "SquidConfig2", sizeof(SquidConfig2), 0);
282 memDataInit(MEM_STATCOUNTERS, "StatCounters", sizeof(StatCounters), 0);
283 memDataInit(MEM_STMEM_BUF, "Store Mem Buffer", SM_PAGE_SIZE,
43a70238 284 Config.memMaxSize / SM_PAGE_SIZE);
acf5589a 285 memDataInit(MEM_STOREENTRY, "StoreEntry", sizeof(StoreEntry), 0);
286 memDataInit(MEM_STORE_CLIENT, "store_client", sizeof(store_client), 0);
287 memDataInit(MEM_SWAPDIR, "SwapDir", sizeof(SwapDir), 0);
288 memDataInit(MEM_USHORTLIST, "ushort_list", sizeof(ushortlist), 0);
289 memDataInit(MEM_WORDLIST, "wordlist", sizeof(wordlist), 0);
59c4d35b 290 memDataInit(MEM_CLIENT_INFO, "ClientInfo", sizeof(ClientInfo), 0);
e55650e3 291 memDataInit(MEM_MD5_DIGEST, "MD5 digest", MD5_DIGEST_CHARS, 0);
c68e9c6b 292 memDataInit(MEM_HELPER, "helper", sizeof(helper), 0);
94439e4e 293 memDataInit(MEM_HELPER_STATEFUL, "stateful_helper", sizeof(statefulhelper), 0);
c68e9c6b 294 memDataInit(MEM_HELPER_REQUEST, "helper_request",
295 sizeof(helper_request), 0);
94439e4e 296 memDataInit(MEM_HELPER_STATEFUL_REQUEST, "helper_stateful_request",
297 sizeof(helper_stateful_request), 0);
c68e9c6b 298 memDataInit(MEM_HELPER_SERVER, "helper_server",
299 sizeof(helper_server), 0);
94439e4e 300 memDataInit(MEM_HELPER_STATEFUL_SERVER, "helper_stateful_server",
301 sizeof(helper_stateful_server), 0);
2391a162 302 memDataInit(MEM_STORE_IO, "storeIOState", sizeof(storeIOState), 0);
58cd5bbd 303 memDataInit(MEM_TLV, "storeSwapTLV", sizeof(tlv), 0);
304 memDataInit(MEM_GEN_CBDATA, "generic_cbdata", sizeof(generic_cbdata), 0);
305 memDataInit(MEM_PUMP_STATE_DATA, "PumpStateData", sizeof(PumpStateData), 0);
306 memDataInit(MEM_CLIENT_REQ_BUF, "clientRequestBuffer", CLIENT_REQ_BUF_SZ, 0);
307 memDataInit(MEM_SWAP_LOG_DATA, "storeSwapLogData", sizeof(storeSwapLogData), 0);
308
58a39dc9 309 /* init string pools */
310 for (i = 0; i < mem_str_pool_count; i++) {
311 StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
312 }
313 cachemgrRegister("mem",
314 "Memory Utilization",
315 memStats, 0, 1);
316}
317
318/*
319 * Test that all entries are initialized
320 */
321void
322memCheckInit(void)
323{
324 mem_type t;
728da2ee 325 for (t = MEM_NONE, t++; t < MEM_MAX; t++) {
d90c79ee 326 if (MEM_DONTFREE == t)
5999b776 327 continue;
acf5589a 328 /*
329 * If you hit this assertion, then you forgot to add a
e13ee7ad 330 * memDataInit() line for type 't'.
acf5589a 331 */
7021844c 332 assert(MemPools[t]);
acf5589a 333 }
334}
335
336void
58a39dc9 337memClean(void)
acf5589a 338{
9fe7e747 339 memCleanModule();
acf5589a 340}
341
acf5589a 342int
343memInUse(mem_type type)
344{
b4832aa9 345 return memPoolInUseCount(MemPools[type]);
acf5589a 346}
347
348/* ick */
349
137ee196 350void
351memFree2K(void *p)
352{
db1cd23c 353 memFree(p, MEM_2K_BUF);
137ee196 354}
355
acf5589a 356void
357memFree4K(void *p)
358{
db1cd23c 359 memFree(p, MEM_4K_BUF);
acf5589a 360}
361
362void
363memFree8K(void *p)
364{
db1cd23c 365 memFree(p, MEM_8K_BUF);
acf5589a 366}
58cd5bbd 367
368void
369memFree16K(void *p)
370{
371 memFree(p, MEM_16K_BUF);
372}
373
374void
375memFree32K(void *p)
376{
377 memFree(p, MEM_32K_BUF);
378}
379
380void
381memFree64K(void *p)
382{
383 memFree(p, MEM_64K_BUF);
384}