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