]> git.ipfire.org Git - thirdparty/squid.git/blame_incremental - compat/xalloc.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / compat / xalloc.cc
... / ...
CommitLineData
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)
20static int malloc_sizes[XMS_DBG_MAXINDEX + 1];
21static int malloc_histo[XMS_DBG_MAXINDEX + 1];
22static int dbg_stat_init = 0;
23
24static int
25XMS_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
36static void
37stat_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
45static int
46malloc_stat(int sz)
47{
48 if (!dbg_stat_init)
49 stat_init();
50
51 return malloc_sizes[XMS_DBG_INDEX(sz)] += 1;
52}
53
54void
55malloc_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
71void *
72xcalloc(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
105void *
106xmalloc(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
136void *
137xrealloc(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
168void
169free_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