mem.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:12k
源码类别:

代理服务器

开发平台:

Unix_Linux

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