Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
mtrace.h
Go to the documentation of this file.
1/** @file mtrace.h
2 */
3/**
4# Memory profiling */
5
6struct {
7 FILE * fp; // trace file
8 size_t total, max; // current and maximum allocated memory
9 size_t overhead, maxoverhead; // current and maximum profiling overhead
10 size_t nr; // current number of records
11 size_t startrss, maxrss; // starting and maximum system ressource usage
12 char * fname; // trace file name
14
15typedef struct {
16 char * func, * file;
17 size_t max, total;
18 int line, id;
19} pmfunc;
20
21typedef struct {
22 size_t id, size;
23} pmdata;
24
25static pmfunc * pmfuncs = NULL;
26static int pmfuncn = 0;
27
28static int pmfunc_index (const char * func, const char * file, int line)
29{
30 pmfunc * p = pmfuncs;
31 for (int i = 0; i < pmfuncn; i++, p++)
32 if (p->line == line && !strcmp(func, p->func) && !strcmp(file, p->file))
33 return p->id;
34 pmfuncn++;
36 p = &pmfuncs[pmfuncn - 1];
37 memset (p, 0, sizeof(pmfunc));
38 p->func = systrdup(func);
39 p->file = systrdup(file);
40 p->line = line;
41 p->id = pmfuncn;
42 if (pmtrace.fp)
43 fprintf (pmtrace.fp, "@ %d %s %s %d\n", pmfuncn, func, file, line);
44 return pmfuncn;
45}
46
47static void pmfunc_trace (pmfunc * f, char c)
48{
49 if (pmtrace.fp)
50 fprintf (pmtrace.fp, "%c %d %ld %ld %ld",
51 c, f->id, pmtrace.nr, pmtrace.total, f->total);
53 if (pmtrace.nr % 1 == 0) {
54 struct rusage usage;
56 if (pmtrace.fp)
57 fprintf (pmtrace.fp, " %ld", usage.ru_maxrss*1024);
58 if (!pmtrace.nr)
59 pmtrace.startrss = usage.ru_maxrss;
60 if (usage.ru_maxrss > pmtrace.maxrss)
61 pmtrace.maxrss = usage.ru_maxrss;
62 }
63@endif
64 if (pmtrace.fp)
65 fputc ('\n', pmtrace.fp);
66 pmtrace.nr++;
67}
68
69static void * pmfunc_alloc (pmdata * d, size_t size,
70 const char * func, const char * file, int line,
71 char c)
72{
73 assert (d != NULL);
75 {
76 d->id = pmfunc_index(func, file, line);
77 d->size = size;
78 pmfunc * f = &pmfuncs[d->id - 1];
79 f->total += size;
80 if (f->total > f->max)
81 f->max = f->total;
82 pmtrace.total += size;
83 pmtrace.overhead += sizeof(pmdata);
84 if (pmtrace.total > pmtrace.max) {
85 pmtrace.max = pmtrace.total;
86 pmtrace.maxoverhead = pmtrace.overhead;
87 }
88 pmfunc_trace (f, c);
89 }
90 return ((char *)d) + sizeof(pmdata);
91}
92
93static void * pmfunc_free (void * ptr, char c)
94{
95 if (!ptr)
96 return ptr;
97 pmdata * d = (pmdata *) (((char *)ptr) - sizeof(pmdata));
98 if (d->id < 1 || d->id > pmfuncn) {
99 fputs ("*** MTRACE: ERROR!: corrupted free()", stderr);
100 if (d->size == 0)
101 fputs (", possible double free()", stderr);
102 else
103 fputs (", not traced?", stderr);
104 fputs (", aborting...\n", stderr);
105 abort();
106 return ptr;
107 }
108 else
110 {
111 pmfunc * f = &pmfuncs[d->id - 1];
112 if (f->total < d->size) {
113 fprintf (stderr, "*** MTRACE: ERROR!: %ld < %ld: corrupted free()?\n",
114 f->total, d->size);
115 abort();
116 }
117 else
118 f->total -= d->size;
119 if (pmtrace.total < d->size) {
120 fprintf (stderr, "*** MTRACE: ERROR!: %ld < %ld: corrupted free()?\n",
121 pmtrace.total, d->size);
122 abort();
123 }
124 else {
125 pmtrace.total -= d->size;
126 pmtrace.overhead -= sizeof(pmdata);
127 }
128 d->id = 0;
129 d->size = 0;
130 pmfunc_trace (f, c);
131 }
132 return d;
133}
134
135static void * pmalloc (size_t size,
136 const char * func, const char * file, int line)
137{
138 return pmfunc_alloc ((pmdata *) sysmalloc (sizeof(pmdata) + size),
139 size, func, file, line, '+');
140}
141
142static void * pcalloc (size_t nmemb, size_t size,
143 const char * func, const char * file, int line)
144{
145 void * p = pmalloc (nmemb*size, func, file, line);
146 return memset (p, 0, nmemb*size);
147}
148
149static void * prealloc (void * ptr, size_t size,
150 const char * func, const char * file, int line)
151{
152 return pmfunc_alloc ((pmdata *) sysrealloc (pmfunc_free(ptr, '<'),
153 sizeof(pmdata) + size),
154 size, func, file, line, '>');
155}
156
157static void pfree (void * ptr,
158 const char * func, const char * file, int line)
159{
160 sysfree (pmfunc_free (ptr, '-'));
161}
162
163static char * pstrdup (const char * s,
164 const char * func, const char * file, int line)
165{
166 char * d = (char *) pmalloc (strlen(s) + 1, func, file, line);
167 return strcpy (d, s);
168}
169
170#if MTRACE < 3
171static int pmaxsort (const void * a, const void * b) {
172 const pmfunc * p1 = a, * p2 = b;
173 return p1->max < p2->max;
174}
175#endif
176
177static int ptotalsort (const void * a, const void * b) {
178 const pmfunc * p1 = (const pmfunc *) a, * p2 = (const pmfunc *) b;
179 return p1->total < p2->total;
180}
181
182static void pmfuncs_free()
183{
184 pmfunc * p = pmfuncs;
185 for (int i = 0; i < pmfuncn; i++, p++) {
186 sysfree (p->func);
187 sysfree (p->file);
188 }
190}
191
192void pmuntrace (void)
193{
194#if MTRACE < 3
196 "*** MTRACE: max resident set size: %10ld bytes\n"
197 "*** MTRACE: max traced memory size: %10ld bytes"
198 " (tracing overhead %.1g%%)\n"
199 "%10s %20s %s\n",
200 pmtrace.maxrss*1024,
201 pmtrace.max, pmtrace.maxoverhead*100./pmtrace.max,
202 "max bytes", "function", "file");
203 qsort (pmfuncs, pmfuncn, sizeof(pmfunc), pmaxsort);
204 pmfunc * p = pmfuncs;
205 for (int i = 0; i < pmfuncn && p->max > 0; i++, p++)
206 fprintf (stderr, "%10ld %20s %s:%d\n",
207 p->max, p->func, p->file, p->line);
208
209 if (pmtrace.fp) {
210 char * fname = pmtrace.fname, * s;
211 while ((s = strchr(fname,'/')))
212 fname = s + 1;
213
214 fputs ("load(\"`echo \f$BASILISK`/mtrace.plot\")\n", pmtrace.fp);
215 fprintf (pmtrace.fp,
216 "plot '%s' u 3:(\f$6-%g) w l t 'ru_maxrss - %.3g',"
217 "total(\"%s\") w l t 'total'",
218 fname,
219 pmtrace.startrss*1024.,
220 pmtrace.startrss*1024.,
221 fname);
222 pmfunc * p = pmfuncs;
223 for (int i = 0; i < pmfuncn && p->max > 0.01*pmtrace.max; i++, p++)
224 fprintf (pmtrace.fp,
225 ",func(\"%s\",%d) w l t '%s'",
226 fname, p->id, p->func);
227 fputc ('\n', pmtrace.fp);
229 "*** MTRACE: To get a graph use: tail -n 2 %s | gnuplot -persist\n",
230 fname);
231 fclose (pmtrace.fp);
232 pmtrace.fp = NULL;
233 sysfree (pmtrace.fname);
234 }
235#endif // MTRACE < 3
236
237 if (pmtrace.total > 0) {
239 pmfunc * p = pmfuncs;
240 for (int i = 0; i < pmfuncn && p->total > 0; i++, p++)
241 fprintf (stderr, "%s:%d: error: %ld bytes leaked here\n",
242 p->file, p->line, p->total);
243 pmfuncs_free();
244 exit(1);
245 }
246 else {
247#if MTRACE < 3
248 fputs ("*** MTRACE: No memory leaks\n", stderr);
249#endif
250 pmfuncs_free();
251 }
252}
const vector a
Definition all-mach.h:59
int x
Definition common.h:76
scalar f[]
The primary fields are:
Definition two-phase.h:56
#define p
Definition tree.h:320
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define func
Definition config.h:120
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define file
Definition config.h:120
#define assert(a)
Definition config.h:107
scalar s
Definition embed-tree.h:56
double d[2]
Definition embed.h:383
scalar int i
Definition embed.h:74
static int line
Definition errors.c:754
size_t maxrss
Definition mtrace.h:11
size_t max
Definition mtrace.h:8
static void * pcalloc(size_t nmemb, size_t size, const char *func, const char *file, int line)
Definition mtrace.h:142
static int pmfunc_index(const char *func, const char *file, int line)
Definition mtrace.h:28
size_t total
Definition mtrace.h:8
static int pmfuncn
Definition mtrace.h:26
static void pmfunc_trace(pmfunc *f, char c)
Definition mtrace.h:47
size_t nr
Definition mtrace.h:10
static int ptotalsort(const void *a, const void *b)
Definition mtrace.h:177
void pmuntrace(void)
Definition mtrace.h:192
static int pmaxsort(const void *a, const void *b)
Definition mtrace.h:171
static void pfree(void *ptr, const char *func, const char *file, int line)
Definition mtrace.h:157
FILE * fp
Definition mtrace.h:7
size_t startrss
Definition mtrace.h:11
static void * pmalloc(size_t size, const char *func, const char *file, int line)
Definition mtrace.h:135
static void * pmfunc_alloc(pmdata *d, size_t size, const char *func, const char *file, int line, char c)
Definition mtrace.h:69
static char * pstrdup(const char *s, const char *func, const char *file, int line)
Definition mtrace.h:163
size_t maxoverhead
Definition mtrace.h:9
static void * pmfunc_free(void *ptr, char c)
Definition mtrace.h:93
static void pmfuncs_free()
Definition mtrace.h:182
static void * prealloc(void *ptr, size_t size, const char *func, const char *file, int line)
Definition mtrace.h:149
struct @9 pmtrace
char * fname
Definition mtrace.h:12
size_t overhead
Definition mtrace.h:9
static pmfunc * pmfuncs
Definition mtrace.h:25
size_t size
size *double * b
size_t id
Definition mtrace.h:22
size_t max
Definition mtrace.h:17
char * file
Definition mtrace.h:16
int id
Definition mtrace.h:18
scalar c
Definition vof.h:57