]> git.ipfire.org Git - thirdparty/squid.git/blame - src/mem.cc
- Separated raw HTTP headers from their "compiled" values. Squid is now
[thirdparty/squid.git] / src / mem.cc
CommitLineData
acf5589a 1
2/*
d8b249ef 3 * $Id: mem.cc,v 1.19 1998/03/20 18:06:45 rousskov Exp $
acf5589a 4 *
7021844c 5 * DEBUG: section 13 High Level Memory Pool Management
acf5589a 6 * AUTHOR: Harvest Derived
7 *
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * --------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by
14 * the National Science Foundation.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31
32#include "squid.h"
33
7021844c 34/* module globals */
acf5589a 35
7021844c 36static MemPool *MemPools[MEM_MAX];
acf5589a 37
9fe7e747 38/* string pools */
39#define mem_str_pool_count 3
40static const struct {
41 const char *name;
42 size_t obj_size;
43} StrPoolsAttrs[mem_str_pool_count] = {
44 { "Short Strings", 36, }, /* to fit rfc1123 and similar */
45 { "Medium Strings", 128, }, /* to fit most urls */
46 { "Long Strings", 512 } /* other */
47};
48static struct { MemPool *pool; } StrPools[mem_str_pool_count];
49static MemMeter StrCountMeter;
50static MemMeter StrVolumeMeter;
51
52
53/* local routines */
54
4cc73db3 55/*
56 * we have a limit on _total_ amount of idle memory so we ignore
57 * max_pages for now
58 */
acf5589a 59static void
7021844c 60memDataInit(mem_type type, const char *name, size_t size, int max_pages_notused)
acf5589a 61{
7021844c 62 assert(name && size);
63 MemPools[type] = memPoolCreate(name, size);
acf5589a 64}
65
9fe7e747 66static void
67memStringStats(StoreEntry * sentry)
68{
69 const char *pfmt = "%-20s\t %d\t %d\n";
70 int i;
71 int pooled_count = 0;
72 size_t pooled_volume = 0;
73 /* heading */
74 storeAppendPrintf(sentry,
75 "String Pool\t Impact\t\t\n"
76 " \t (%%strings)\t (%%volume)\n");
77 /* table body */
78 for (i = 0; i < mem_str_pool_count; i++) {
79 const MemPool *pool = StrPools[i].pool;
80 const int plevel = pool->meter.inuse.level;
81 storeAppendPrintf(sentry, pfmt,
82 pool->label,
83 xpercentInt(plevel, StrCountMeter.level),
84 xpercentInt(plevel*pool->obj_size, StrVolumeMeter.level));
85 pooled_count += plevel;
86 pooled_volume += plevel*pool->obj_size;
87 }
88 /* malloc strings */
89 storeAppendPrintf(sentry, pfmt,
90 "Other Strings",
91 xpercentInt(StrCountMeter.level-pooled_count, StrCountMeter.level),
92 xpercentInt(StrVolumeMeter.level-pooled_volume, StrVolumeMeter.level));
93}
94
acf5589a 95static void
7021844c 96memStats(StoreEntry * sentry)
acf5589a 97{
7021844c 98 storeBuffer(sentry);
b4832aa9 99 memReport(sentry);
9fe7e747 100 memStringStats(sentry);
7021844c 101 storeBufferFlush(sentry);
acf5589a 102}
103
7021844c 104
acf5589a 105/*
9fe7e747 106 * public routines
acf5589a 107 */
108
9fe7e747 109
7021844c 110/* find appropriate pool and use it (pools always init buffer with 0s) */
acf5589a 111void *
7021844c 112memAllocate(mem_type type)
acf5589a 113{
7021844c 114 return memPoolAlloc(MemPools[type]);
acf5589a 115}
116
7021844c 117/* find appropriate pool and use it */
acf5589a 118void
119memFree(mem_type type, void *p)
120{
7021844c 121 memPoolFree(MemPools[type], p);
acf5589a 122}
123
9fe7e747 124/* allocate a variable size buffer using best-fit pool */
125void *
126memAllocBuf(size_t net_size, size_t *gross_size)
127{
128 int i;
129 MemPool *pool = NULL;
130 assert(gross_size);
131 for (i = 0; i < mem_str_pool_count; i++) {
132 if (net_size <= StrPoolsAttrs[i].obj_size) {
133 pool = StrPools[i].pool;
134 break;
135 }
136 }
137 *gross_size = pool ? pool->obj_size : net_size;
138 assert(*gross_size >= net_size);
139 memMeterInc(StrCountMeter);
140 memMeterAdd(StrVolumeMeter, *gross_size);
141 return pool ? memPoolAlloc(pool) : xcalloc(1, net_size);
142}
143
144/* free buffer allocated with memAllocBuf() */
145void
146memFreeBuf(size_t size, void *buf)
147{
148 int i;
149 MemPool *pool = NULL;
150 assert(size && buf);
151 for (i = 0; i < mem_str_pool_count; i++) {
152 if (size <= StrPoolsAttrs[i].obj_size) {
153 assert(size == StrPoolsAttrs[i].obj_size);
154 pool = StrPools[i].pool;
155 break;
156 }
157 }
158 memMeterDec(StrCountMeter);
159 memMeterDel(StrVolumeMeter, size);
160 pool ? memPoolFree(pool, buf) : xfree(buf);
161}
162
acf5589a 163void
164memInit(void)
165{
9fe7e747 166 int i;
acf5589a 167 mem_type t;
7021844c 168 memInitModule();
169 /* set all pointers to null */
170 memset(MemPools, '\0', sizeof(MemPools));
171 /*
172 * it does not hurt much to have a lot of pools since sizeof(MemPool) is
173 * small; someday we will figure out what to do with all the entries here
174 * that are never used or used only once; perhaps we should simply use
175 * malloc() for those? @?@
176 */
acf5589a 177 memDataInit(MEM_4K_BUF, "4K Buffer", 4096, 10);
178 memDataInit(MEM_8K_BUF, "8K Buffer", 8192, 10);
179 memDataInit(MEM_ACCESSLOGENTRY, "AccessLogEntry",
180 sizeof(AccessLogEntry), 10);
181 memDataInit(MEM_ACL, "acl", sizeof(acl), 0);
182 memDataInit(MEM_ACLCHECK_T, "aclCheck_t", sizeof(aclCheck_t), 0);
183 memDataInit(MEM_ACL_ACCESS, "acl_access", sizeof(acl_access), 0);
184 memDataInit(MEM_ACL_DENY_INFO_LIST, "acl_deny_info_list",
185 sizeof(acl_deny_info_list), 0);
186 memDataInit(MEM_ACL_IP_DATA, "acl_ip_data", sizeof(acl_ip_data), 0);
187 memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0);
188 memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0);
189 memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0);
190 memDataInit(MEM_AIO_RESULT_T, "aio_result_t", sizeof(aio_result_t), 0);
acf5589a 191 memDataInit(MEM_CACHEMGR_PASSWD, "cachemgr_passwd",
192 sizeof(cachemgr_passwd), 0);
193 memDataInit(MEM_CLIENTHTTPREQUEST, "clientHttpRequest",
194 sizeof(clientHttpRequest), 0);
195 memDataInit(MEM_CLOSE_HANDLER, "close_handler", sizeof(close_handler), 0);
196 memDataInit(MEM_COMMWRITESTATEDATA, "CommWriteStateData",
197 sizeof(CommWriteStateData), 0);
198 memDataInit(MEM_CONNSTATEDATA, "ConnStateData", sizeof(ConnStateData), 0);
199 memDataInit(MEM_DISK_BUF, "Disk I/O Buffer", DISK_PAGE_SIZE, 200);
200 memDataInit(MEM_DLINK_LIST, "dlink_list", sizeof(dlink_list), 10);
201 memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10);
202 memDataInit(MEM_DNSSERVER_T, "dnsserver_t", sizeof(dnsserver_t), 0);
203 memDataInit(MEM_DNSSTATDATA, "dnsStatData", sizeof(dnsStatData), 0);
204 memDataInit(MEM_DOMAIN_PING, "domain_ping", sizeof(domain_ping), 0);
205 memDataInit(MEM_DOMAIN_TYPE, "domain_type", sizeof(domain_type), 0);
206 memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
207 memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
208 memDataInit(MEM_ERRORSTATE, "ErrorState", sizeof(ErrorState), 0);
209 memDataInit(MEM_FILEMAP, "fileMap", sizeof(fileMap), 0);
210 memDataInit(MEM_FQDNCACHE_ENTRY, "fqdncache_entry",
211 sizeof(fqdncache_entry), 0);
b817e5e9 212 memDataInit(MEM_FQDNCACHE_PENDING, "fqdn_pending",
213 sizeof(fqdn_pending), 0);
acf5589a 214 memDataInit(MEM_HASH_LINK, "hash_link", sizeof(hash_link), 0);
215 memDataInit(MEM_HASH_TABLE, "hash_table", sizeof(hash_table), 0);
216 memDataInit(MEM_HIERARCHYLOGENTRY, "HierarchyLogEntry",
217 sizeof(HierarchyLogEntry), 0);
4cc73db3 218 memDataInit(MEM_HTTP_STATE_DATA, "HttpStateData", sizeof(HttpStateData), 0);
d8b249ef 219 memDataInit(MEM_HTTP_REPLY, "HttpReply", sizeof(HttpReply), 0);
220 memDataInit(MEM_HTTP_HDR_ENTRY, "HttpHeaderEntry", sizeof(HttpHeaderEntry), 0);
7faf2bdb 221 memDataInit(MEM_HTTP_HDR_CC, "HttpHdrCc", sizeof(HttpHdrCc), 0);
eed12adc 222 memDataInit(MEM_HTTP_HDR_RANGE_SPEC, "HttpHdrRangeSpec", sizeof(HttpHdrRangeSpec), 0);
223 memDataInit(MEM_HTTP_HDR_RANGE, "HttpHdrRange", sizeof(HttpHdrRange), 0);
d76fcfa7 224 memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0);
acf5589a 225 memDataInit(MEM_ICPUDPDATA, "icpUdpData", sizeof(icpUdpData), 0);
226 memDataInit(MEM_ICP_COMMON_T, "icp_common_t", sizeof(icp_common_t), 0);
227 memDataInit(MEM_ICP_PING_DATA, "icp_ping_data", sizeof(icp_ping_data), 0);
228 memDataInit(MEM_INTLIST, "intlist", sizeof(intlist), 0);
229 memDataInit(MEM_IOSTATS, "iostats", sizeof(iostats), 0);
59c4d35b 230 memDataInit(MEM_IPCACHE_PENDING, "ip_pending", sizeof(ip_pending), 0);
acf5589a 231 memDataInit(MEM_IPCACHE_ENTRY, "ipcache_entry", sizeof(ipcache_entry), 0);
232 memDataInit(MEM_MEMOBJECT, "MemObject", sizeof(MemObject),
233 Squid_MaxFD >> 3);
234 memDataInit(MEM_MEM_HDR, "mem_hdr", sizeof(mem_hdr), 0);
235 memDataInit(MEM_MEM_NODE, "mem_node", sizeof(mem_node), 0);
acf5589a 236 memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
237 memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
238 memDataInit(MEM_NET_DB_PEER, "net_db_peer", sizeof(net_db_peer), 0);
239 memDataInit(MEM_PEER, "peer", sizeof(peer), 0);
240 memDataInit(MEM_PINGERECHODATA, "pingerEchoData",
241 sizeof(pingerEchoData), 0);
242 memDataInit(MEM_PINGERREPLYDATA, "pingerReplyData",
243 sizeof(pingerReplyData), 0);
acf5589a 244 memDataInit(MEM_PS_STATE, "ps_state", sizeof(ps_state), 0);
245 memDataInit(MEM_REFRESH_T, "refresh_t", sizeof(refresh_t), 0);
246 memDataInit(MEM_RELIST, "relist", sizeof(relist), 0);
247 memDataInit(MEM_REQUEST_T, "request_t", sizeof(request_t),
248 Squid_MaxFD >> 3);
acf5589a 249 memDataInit(MEM_SQUIDCONFIG, "SquidConfig", sizeof(SquidConfig), 0);
250 memDataInit(MEM_SQUIDCONFIG2, "SquidConfig2", sizeof(SquidConfig2), 0);
251 memDataInit(MEM_STATCOUNTERS, "StatCounters", sizeof(StatCounters), 0);
252 memDataInit(MEM_STMEM_BUF, "Store Mem Buffer", SM_PAGE_SIZE,
253 Config.Mem.maxSize / SM_PAGE_SIZE);
254 memDataInit(MEM_STOREENTRY, "StoreEntry", sizeof(StoreEntry), 0);
255 memDataInit(MEM_STORE_CLIENT, "store_client", sizeof(store_client), 0);
256 memDataInit(MEM_SWAPDIR, "SwapDir", sizeof(SwapDir), 0);
257 memDataInit(MEM_USHORTLIST, "ushort_list", sizeof(ushortlist), 0);
258 memDataInit(MEM_WORDLIST, "wordlist", sizeof(wordlist), 0);
59c4d35b 259 memDataInit(MEM_CLIENT_INFO, "ClientInfo", sizeof(ClientInfo), 0);
7021844c 260 /* test that all entries are initialized */
acf5589a 261 for (t = MEM_NONE + 1; t < MEM_MAX; t++) {
acf5589a 262 /*
263 * If you hit this assertion, then you forgot to add a
264 * memDataInit() line for type 't' above.
265 */
7021844c 266 assert(MemPools[t]);
acf5589a 267 }
9fe7e747 268 /* init string pools */
269 for (i = 0; i < mem_str_pool_count; i++) {
270 StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
271 }
22f3fd98 272 cachemgrRegister("mem",
273 "Memory Utilization",
274 memStats, 0);
acf5589a 275}
276
277void
7021844c 278memClean()
acf5589a 279{
9fe7e747 280 memCleanModule();
acf5589a 281}
282
acf5589a 283int
284memInUse(mem_type type)
285{
b4832aa9 286 return memPoolInUseCount(MemPools[type]);
acf5589a 287}
288
289/* ick */
290
291void
292memFree4K(void *p)
293{
294 memFree(MEM_4K_BUF, p);
295}
296
297void
298memFree8K(void *p)
299{
300 memFree(MEM_8K_BUF, p);
301}
302
303void
304memFreeDISK(void *p)
305{
306 memFree(MEM_DISK_BUF, p);
307}