]> git.ipfire.org Git - thirdparty/squid.git/blob - compat/xalloc.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / compat / xalloc.cc
1 /*
2 * Copyright (C) 1996-2023 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 #include "squid.h"
10 #include "compat/xalloc.h"
11
12 #if XMALLOC_STATISTICS
13 #define XMS_DBG_MAXSIZE (1024*1024)
14 #define XMS_DBG_SPLIT (256) /* mallocs below this value are tracked with DBG_GRAIN_SM precision instead of DBG_GRAIN */
15 #define XMS_DBG_GRAIN (16)
16 #define XMS_DBG_GRAIN_SM (4)
17 #define XMS_DBG_OFFSET (XMS_DBG_SPLIT/XMS_DBG_GRAIN_SM - XMS_DBG_SPLIT/XMS_DBG_GRAIN )
18 #define XMS_DBG_MAXINDEX (XMS_DBG_MAXSIZE/XMS_DBG_GRAIN + XMS_DBG_OFFSET)
19 static int malloc_sizes[XMS_DBG_MAXINDEX + 1];
20 static int malloc_histo[XMS_DBG_MAXINDEX + 1];
21 static int dbg_stat_init = 0;
22
23 static int
24 XMS_DBG_INDEX(int sz)
25 {
26 if (sz >= XMS_DBG_MAXSIZE)
27 return XMS_DBG_MAXINDEX;
28
29 if (sz <= XMS_DBG_SPLIT)
30 return (sz + XMS_DBG_GRAIN_SM - 1) / XMS_DBG_GRAIN_SM;
31
32 return (sz + XMS_DBG_GRAIN - 1) / XMS_DBG_GRAIN + XMS_DBG_OFFSET;
33 }
34
35 static void
36 stat_init(void)
37 {
38 for (int i = 0; i <= XMS_DBG_MAXINDEX; ++i)
39 malloc_sizes[i] = malloc_histo[i] = 0;
40
41 dbg_stat_init = 1;
42 }
43
44 static int
45 malloc_stat(int sz)
46 {
47 if (!dbg_stat_init)
48 stat_init();
49
50 return malloc_sizes[XMS_DBG_INDEX(sz)] += 1;
51 }
52
53 void
54 malloc_statistics(void (*func) (int, int, int, void *), void *data)
55 {
56 int i = 0;
57
58 for (; i <= XMS_DBG_SPLIT; i += XMS_DBG_GRAIN_SM)
59 func(i, malloc_sizes[XMS_DBG_INDEX(i)], malloc_histo[XMS_DBG_INDEX(i)], data);
60
61 i -= XMS_DBG_GRAIN_SM;
62
63 for (; i <= XMS_DBG_MAXSIZE; i += XMS_DBG_GRAIN)
64 func(i, malloc_sizes[XMS_DBG_INDEX(i)], malloc_histo[XMS_DBG_INDEX(i)], data);
65
66 memcpy(&malloc_histo, &malloc_sizes, sizeof(malloc_sizes));
67 }
68 #endif /* XMALLOC_STATISTICS */
69
70 void *
71 xcalloc(size_t n, size_t sz)
72 {
73 if (n < 1)
74 n = 1;
75
76 if (sz < 1)
77 sz = 1;
78
79 void *p = calloc(n, sz);
80
81 if (!p) {
82 if (failure_notify) {
83 static char msg[128];
84 snprintf(msg, 128, "xcalloc: Unable to allocate %" PRIuSIZE " blocks of %" PRIuSIZE " bytes!\n", n, sz);
85 failure_notify(msg);
86 } else {
87 perror("xcalloc");
88 }
89 exit(1);
90 }
91
92 #if XMALLOC_STATISTICS
93 malloc_stat(sz * n);
94 #endif
95
96 return p;
97 }
98
99 void *
100 xmalloc(size_t sz)
101 {
102 if (sz < 1)
103 sz = 1;
104
105 void *p = malloc(sz);
106
107 if (!p) {
108 if (failure_notify) {
109 static char msg[128];
110 snprintf(msg, 128, "xmalloc: Unable to allocate %" PRIuSIZE " bytes!\n", sz);
111 failure_notify(msg);
112 } else {
113 perror("malloc");
114 }
115 exit(1);
116 }
117
118 #if XMALLOC_STATISTICS
119 malloc_stat(sz);
120 #endif
121
122 return (p);
123 }
124
125 void *
126 xrealloc(void *s, size_t sz)
127 {
128 if (sz < 1)
129 sz = 1;
130
131 void *p= realloc(s, sz);
132
133 if (!p) {
134 if (failure_notify) {
135 static char msg[128];
136 snprintf(msg, 128, "xrealloc: Unable to reallocate %" PRIuSIZE " bytes!\n", sz);
137 failure_notify(msg);
138 } else {
139 perror("realloc");
140 }
141
142 exit(1);
143 }
144
145 #if XMALLOC_STATISTICS
146 malloc_stat(sz);
147 #endif
148
149 return (p);
150 }
151
152 void
153 free_const(const void *s_const)
154 {
155 void *s = const_cast<void *>(s_const);
156
157 free(s);
158 }
159