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