]> git.ipfire.org Git - thirdparty/squid.git/blame - lib/util.c
Replaced 'cache_hot_vm_factor' with 'max_hotvm_obj_size'.
[thirdparty/squid.git] / lib / util.c
CommitLineData
30a4f2a8 1/*
67508012 2 * $Id: util.c,v 1.19 1996/09/20 06:28:22 wessels Exp $
30a4f2a8 3 *
4 * DEBUG:
5 * AUTHOR: Harvest Derived
6 *
7 * SQUID Internet Object Cache http://www.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
13 * the National Science Foundation.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
7fc9f088 30
30a4f2a8 31/*
32 * Copyright (c) 1994, 1995. All rights reserved.
33 *
34 * The Harvest software was developed by the Internet Research Task
35 * Force Research Group on Resource Discovery (IRTF-RD):
36 *
37 * Mic Bowman of Transarc Corporation.
38 * Peter Danzig of the University of Southern California.
39 * Darren R. Hardy of the University of Colorado at Boulder.
40 * Udi Manber of the University of Arizona.
41 * Michael F. Schwartz of the University of Colorado at Boulder.
42 * Duane Wessels of the University of Colorado at Boulder.
43 *
44 * This copyright notice applies to software in the Harvest
45 * ``src/'' directory only. Users should consult the individual
46 * copyright notices in the ``components/'' subdirectories for
47 * copyright information about other software bundled with the
48 * Harvest source code distribution.
49 *
50 * TERMS OF USE
51 *
52 * The Harvest software may be used and re-distributed without
53 * charge, provided that the software origin and research team are
54 * cited in any use of the system. Most commonly this is
55 * accomplished by including a link to the Harvest Home Page
56 * (http://harvest.cs.colorado.edu/) from the query page of any
57 * Broker you deploy, as well as in the query result pages. These
58 * links are generated automatically by the standard Broker
59 * software distribution.
60 *
61 * The Harvest software is provided ``as is'', without express or
62 * implied warranty, and with no support nor obligation to assist
63 * in its use, correction, modification or enhancement. We assume
64 * no liability with respect to the infringement of copyrights,
65 * trade secrets, or any patents, and are not responsible for
66 * consequential damages. Proper use of the Harvest software is
67 * entirely the responsibility of the user.
68 *
69 * DERIVATIVE WORKS
70 *
71 * Users may make derivative works from the Harvest software, subject
72 * to the following constraints:
73 *
74 * - You must include the above copyright notice and these
75 * accompanying paragraphs in all forms of derivative works,
76 * and any documentation and other materials related to such
77 * distribution and use acknowledge that the software was
78 * developed at the above institutions.
79 *
80 * - You must notify IRTF-RD regarding your distribution of
81 * the derivative work.
82 *
83 * - You must clearly notify users that your are distributing
84 * a modified version and not the original Harvest software.
85 *
86 * - Any derivative product is also subject to these copyright
87 * and use restrictions.
88 *
89 * Note that the Harvest software is NOT in the public domain. We
90 * retain copyright, as specified above.
91 *
92 * HISTORY OF FREE SOFTWARE STATUS
93 *
94 * Originally we required sites to license the software in cases
95 * where they were going to build commercial products/services
96 * around Harvest. In June 1995 we changed this policy. We now
97 * allow people to use the core Harvest software (the code found in
98 * the Harvest ``src/'' directory) for free. We made this change
99 * in the interest of encouraging the widest possible deployment of
100 * the technology. The Harvest software is really a reference
101 * implementation of a set of protocols and formats, some of which
102 * we intend to standardize. We encourage commercial
103 * re-implementations of code complying to this set of standards.
104 */
0d94e9fe 105
30a4f2a8 106#include "config.h"
107
108#if HAVE_STDIO_H
090089c4 109#include <stdio.h>
30a4f2a8 110#endif
111#if HAVE_STDLIB_H
090089c4 112#include <stdlib.h>
30a4f2a8 113#endif
114#if HAVE_STRING_H
090089c4 115#include <string.h>
30a4f2a8 116#endif
673d7a4d 117#if HAVE_CTYPE_H
118#include <ctype.h>
119#endif
30a4f2a8 120#if HAVE_UNISTD_H
090089c4 121#include <unistd.h>
30a4f2a8 122#endif
123#if HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)
090089c4 124#include <malloc.h>
983061ed 125#endif
30a4f2a8 126#if HAVE_ERRNO_H
090089c4 127#include <errno.h>
30a4f2a8 128#endif
090089c4 129
f606f345 130#include "ansiproto.h"
473471f2 131#include "util.h"
30a4f2a8 132
67508012 133void (*failure_notify) _PARAMS((char *)) = NULL;
090089c4 134static char msg[128];
135
35570558 136extern int sys_nerr;
30a4f2a8 137#if NEED_SYS_ERRLIST && !defined(_SQUID_NETBSD_)
35570558 138extern char *sys_errlist[];
139#endif
140
30a4f2a8 141#if XMALLOC_STATISTICS
142#define DBG_MAXSIZE (1024*1024)
143#define DBG_GRAIN (16)
144#define DBG_MAXINDEX (DBG_MAXSIZE/DBG_GRAIN)
145#define DBG_INDEX(sz) (sz<DBG_MAXSIZE?(sz+DBG_GRAIN-1)/DBG_GRAIN:DBG_MAXINDEX)
146static int malloc_sizes[DBG_MAXINDEX + 1];
147static int dbg_stat_init = 0;
148
b8d8561b 149static void
0673c0ba 150stat_init(void)
30a4f2a8 151{
152 int i;
153 for (i = 0; i <= DBG_MAXINDEX; i++)
154 malloc_sizes[i] = 0;
155 dbg_stat_init = 1;
156}
157
b8d8561b 158static int
159malloc_stat(int sz)
30a4f2a8 160{
161 if (!dbg_stat_init)
162 stat_init();
163 return malloc_sizes[DBG_INDEX(sz)] += 1;
164}
165
b8d8561b 166void
5d3ec1a4 167malloc_statistics(void (*func) (int, int, void *), void *data)
30a4f2a8 168{
169 int i;
170 for (i = 0; i <= DBG_MAXSIZE; i += DBG_GRAIN)
171 func(i, malloc_sizes[DBG_INDEX(i)], data);
172}
173#endif /* XMALLOC_STATISTICS */
174
090089c4 175
45e93040 176
1d012b4c 177#if XMALLOC_DEBUG
68b468e5 178#define DBG_ARRY_SZ (1<<10)
179#define DBG_ARRY_BKTS (1<<8)
8c6551ac 180static void *malloc_ptrs[DBG_ARRY_BKTS][DBG_ARRY_SZ];
181static int malloc_size[DBG_ARRY_BKTS][DBG_ARRY_SZ];
45e93040 182static int dbg_initd = 0;
8c6551ac 183static int B = 0;
45e93040 184static int I = 0;
185static void *P;
186static void *Q;
187
b8d8561b 188static void
0673c0ba 189check_init(void)
45e93040 190{
68b468e5 191 for (B = 0; B < DBG_ARRY_BKTS; B++) {
30a4f2a8 192 for (I = 0; I < DBG_ARRY_SZ; I++) {
193 malloc_ptrs[B][I] = NULL;
194 malloc_size[B][I] = 0;
195 }
45e93040 196 }
197 dbg_initd = 1;
198}
199
b8d8561b 200static void
201check_free(void *s)
45e93040 202{
8c6551ac 203 B = (((int) s) >> 4) & 0xFF;
45e93040 204 for (I = 0; I < DBG_ARRY_SZ; I++) {
8c6551ac 205 if (malloc_ptrs[B][I] != s)
45e93040 206 continue;
8c6551ac 207 malloc_ptrs[B][I] = NULL;
208 malloc_size[B][I] = 0;
45e93040 209 break;
210 }
211 if (I == DBG_ARRY_SZ) {
212 sprintf(msg, "xfree: ERROR: s=%p not found!", s);
213 (*failure_notify) (msg);
214 }
215}
216
b8d8561b 217static void
218check_malloc(void *p, size_t sz)
45e93040 219{
220 if (!dbg_initd)
221 check_init();
7fc9f088 222 B = (((int) p) >> 4) & 0xFF;
45e93040 223 for (I = 0; I < DBG_ARRY_SZ; I++) {
8c6551ac 224 if ((P = malloc_ptrs[B][I]) == NULL)
45e93040 225 continue;
8c6551ac 226 Q = P + malloc_size[B][I];
45e93040 227 if (P <= p && p < Q) {
228 sprintf(msg, "xmalloc: ERROR: p=%p falls in P=%p+%d",
8c6551ac 229 p, P, malloc_size[B][I]);
45e93040 230 (*failure_notify) (msg);
231 }
232 }
233 for (I = 0; I < DBG_ARRY_SZ; I++) {
8c6551ac 234 if ((P = malloc_ptrs[B][I]))
45e93040 235 continue;
8c6551ac 236 malloc_ptrs[B][I] = p;
237 malloc_size[B][I] = (int) sz;
45e93040 238 break;
239 }
240 if (I == DBG_ARRY_SZ)
241 (*failure_notify) ("xmalloc: debug out of array space!");
242}
243#endif
244
7fc9f088 245#if XMALLOC_COUNT && !HAVE_MALLOCBLKSIZE
b8d8561b 246int
247mallocblksize(void *p)
7fc9f088 248{
249 B = (((int) p) >> 4) & 0xFF;
250 for (I = 0; I < DBG_ARRY_SZ; I++) {
251 if (malloc_ptrs[B][I] == p)
252 return malloc_size[B][I];
253 }
254 return 0;
255}
256#endif
257
68b468e5 258#ifdef XMALLOC_COUNT
b8d8561b 259static void
260xmalloc_count(void *p, int sign)
68b468e5 261{
7fc9f088 262 size_t sz;
263 static size_t total = 0;
264 int memoryAccounted();
265 int mallinfoTotal();
266 sz = mallocblksize(p) * sign;
267 total += sz;
268 fprintf(stderr, "xmalloc_count=%9d accounted=%9d mallinfo=%9d\n",
269 (int) total,
270 memoryAccounted(),
271 mallinfoTotal());
68b468e5 272}
b8d8561b 273
68b468e5 274#endif /* XMALLOC_COUNT */
275
090089c4 276/*
277 * xmalloc() - same as malloc(3). Used for portability.
278 * Never returns NULL; fatal on error.
279 */
b8d8561b 280void *
281xmalloc(size_t sz)
090089c4 282{
283 static void *p;
284
285 if (sz < 1)
286 sz = 1;
287 if ((p = malloc(sz)) == NULL) {
288 if (failure_notify) {
289 sprintf(msg, "xmalloc: Unable to allocate %d bytes!\n",
290 (int) sz);
291 (*failure_notify) (msg);
292 } else {
293 perror("malloc");
294 }
295 exit(1);
296 }
1d012b4c 297#if XMALLOC_DEBUG
45e93040 298 check_malloc(p, sz);
30a4f2a8 299#endif
300#if XMALLOC_STATISTICS
301 malloc_stat(sz);
68b468e5 302#endif
303#if XMALLOC_COUNT
304 xmalloc_count(p, 1);
45e93040 305#endif
090089c4 306 return (p);
307}
308
309/*
310 * xfree() - same as free(3). Will not call free(3) if s == NULL.
311 */
b8d8561b 312void
313xfree(void *s)
090089c4 314{
68b468e5 315#if XMALLOC_COUNT
316 xmalloc_count(s, -1);
7fc9f088 317#endif
318#if XMALLOC_DEBUG
319 check_free(s);
45e93040 320#endif
321 if (s != NULL)
090089c4 322 free(s);
45e93040 323}
324
325/* xxfree() - like xfree(), but we already know s != NULL */
b8d8561b 326void
327xxfree(void *s)
45e93040 328{
68b468e5 329#if XMALLOC_COUNT
330 xmalloc_count(s, -1);
7fc9f088 331#endif
332#if XMALLOC_DEBUG
333 check_free(s);
45e93040 334#endif
335 free(s);
090089c4 336}
337
338/*
339 * xrealloc() - same as realloc(3). Used for portability.
340 * Never returns NULL; fatal on error.
341 */
b8d8561b 342void *
343xrealloc(void *s, size_t sz)
090089c4 344{
345 static void *p;
346
68b468e5 347#if XMALLOC_COUNT
348 xmalloc_count(s, -1);
349#endif
350
090089c4 351 if (sz < 1)
352 sz = 1;
353 if ((p = realloc(s, sz)) == NULL) {
354 if (failure_notify) {
355 sprintf(msg, "xrealloc: Unable to reallocate %d bytes!\n",
356 (int) sz);
357 (*failure_notify) (msg);
358 } else {
359 perror("realloc");
360 }
361 exit(1);
362 }
1d012b4c 363#if XMALLOC_DEBUG
45e93040 364 check_malloc(p, sz);
30a4f2a8 365#endif
366#if XMALLOC_STATISTICS
367 malloc_stat(sz);
68b468e5 368#endif
369#if XMALLOC_COUNT
370 xmalloc_count(p, 1);
45e93040 371#endif
090089c4 372 return (p);
373}
374
375/*
376 * xcalloc() - same as calloc(3). Used for portability.
377 * Never returns NULL; fatal on error.
378 */
b8d8561b 379void *
380xcalloc(int n, size_t sz)
090089c4 381{
382 static void *p;
383
384 if (n < 1)
385 n = 1;
386 if (sz < 1)
387 sz = 1;
388 if ((p = calloc(n, sz)) == NULL) {
389 if (failure_notify) {
390 sprintf(msg, "xcalloc: Unable to allocate %d blocks of %d bytes!\n",
391 (int) n, (int) sz);
392 (*failure_notify) (msg);
393 } else {
394 perror("xcalloc");
395 }
396 exit(1);
397 }
1d012b4c 398#if XMALLOC_DEBUG
45e93040 399 check_malloc(p, sz * n);
30a4f2a8 400#endif
401#if XMALLOC_STATISTICS
402 malloc_stat(sz);
68b468e5 403#endif
404#if XMALLOC_COUNT
405 xmalloc_count(p, 1);
45e93040 406#endif
090089c4 407 return (p);
408}
409
410/*
411 * xstrdup() - same as strdup(3). Used for portability.
412 * Never returns NULL; fatal on error.
413 */
b8d8561b 414char *
415xstrdup(char *s)
090089c4 416{
417 static char *p = NULL;
30a4f2a8 418 size_t sz;
090089c4 419
420 if (s == NULL) {
421 if (failure_notify) {
422 (*failure_notify) ("xstrdup: tried to dup a NULL pointer!\n");
423 } else {
424 fprintf(stderr, "xstrdup: tried to dup a NULL pointer!\n");
425 }
426 exit(1);
427 }
428 sz = strlen(s);
30a4f2a8 429 p = xmalloc((size_t) sz + 1);
090089c4 430 memcpy(p, s, sz); /* copy string */
431 p[sz] = '\0'; /* terminate string */
432 return (p);
433}
434
090089c4 435/*
436 * xstrerror() - return sys_errlist[errno];
437 */
b8d8561b 438char *
0673c0ba 439xstrerror(void)
090089c4 440{
35570558 441 static char xstrerror_buf[BUFSIZ];
35570558 442 if (errno < 0 || errno >= sys_nerr)
090089c4 443 return ("Unknown");
0f5efab0 444#if HAVE_STRERROR
445 sprintf(xstrerror_buf, "(%d) %s", errno, strerror(errno));
446#else
35570558 447 sprintf(xstrerror_buf, "(%d) %s", errno, sys_errlist[errno]);
0f5efab0 448#endif /* HAVE_STRERROR */
35570558 449 return xstrerror_buf;
090089c4 450}
451
45e93040 452#if !HAVE_STRDUP
453/* define for systems that don't have strdup */
b8d8561b 454char *
455strdup(char *s)
45e93040 456{
457 return (xstrdup(s));
458}
459#endif
460
b8d8561b 461void
462xmemcpy(void *from, void *to, int len)
090089c4 463{
30a4f2a8 464#if HAVE_MEMMOVE
465 (void) memmove(from, to, len);
466#elif HAVE_BCOPY
467 bcopy(to, from, len);
468#else
469 (void) memcpy(from, to, len);
090089c4 470#endif
30a4f2a8 471}
673d7a4d 472
b8d8561b 473void
474Tolower(char *q)
673d7a4d 475{
476 char *s = q;
477 while (*s) {
b8d8561b 478 *s = tolower((unsigned char) *s);
479 s++;
673d7a4d 480 }
481}