2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
36 #define _(msgid) gettext(msgid)
44 #define BACKTRACE(fn) { \
48 nptrs = backtrace(buffer, 20); \
49 strings = backtrace_symbols(buffer, nptrs); \
50 for (n = 0; n < nptrs; n++) \
51 fprintf(stderr, "BACKTRACE (%s) %i: %s\n", fn, n, strings[n]); \
52 fprintf(stderr, "\n"); \
64 #define _ gettext(msgid)
71 struct memlist_s
*next
;
74 static struct memlist_s
*memlist
;
75 static pthread_mutex_t mem_mutex
;
77 static size_t allocations
, deallocations
;
86 pthread_mutex_init (&mem_mutex
, NULL
);
92 memlist_remove (void *ptr
, const char *func
)
94 struct memlist_s
*m
, *last
= NULL
, *p
;
96 pthread_mutex_lock (&mem_mutex
);
98 for (m
= memlist
; m
; m
= m
->next
)
103 fprintf (stderr
, "%s: %p %i\n", func
, ptr
, m
->size
);
105 memzero (m
->ptr
, m
->size
);
119 pthread_mutex_unlock (&mem_mutex
);
126 pthread_mutex_unlock (&mem_mutex
);
131 memlist_prepend (struct memlist_s
*new)
133 pthread_mutex_lock (&mem_mutex
);
139 pthread_mutex_unlock (&mem_mutex
);
148 if (!memlist_remove (ptr
, __FUNCTION__
))
150 warnx (_("%s: %p not found"), __FUNCTION__
, ptr
);
156 xmalloc (size_t size
)
161 if ((m
= (struct memlist_s
*) malloc (sizeof (struct memlist_s
))) == NULL
)
164 if ((p
= (void *) malloc (size
)) == NULL
)
174 fprintf (stderr
, "%s: %p %u\n", __FUNCTION__
, p
, size
);
175 BACKTRACE (__FUNCTION__
);
181 xcalloc (size_t nmemb
, size_t size
)
186 if ((m
= (struct memlist_s
*) malloc (sizeof (struct memlist_s
))) == NULL
)
189 if ((p
= calloc (nmemb
, size
)) == NULL
)
196 m
->size
= nmemb
* size
;
199 fprintf (stderr
, "%s: %p %i\n", __FUNCTION__
, p
, nmemb
* size
);
200 BACKTRACE (__FUNCTION__
);
206 xrealloc (void *ptr
, size_t size
)
218 return xmalloc (size
);
220 pthread_mutex_lock (&mem_mutex
);
222 for (m
= memlist
; m
; m
= m
->next
)
226 if ((p
= (void *) malloc (size
)) == NULL
)
228 pthread_mutex_unlock (&mem_mutex
);
232 memcpy (p
, m
->ptr
, size
< m
->size
? size
: m
->size
);
233 memzero (m
->ptr
, m
->size
);
238 fprintf (stderr
, "%s: %p %u\n", __FUNCTION__
, p
, size
);
239 BACKTRACE (__FUNCTION__
);
241 pthread_mutex_unlock (&mem_mutex
);
246 warnx (_("%s: %p not found"), __FUNCTION__
, ptr
);
247 pthread_mutex_unlock (&mem_mutex
);
257 pthread_mutex_lock (&mem_mutex
);
259 for (m
= memlist
; m
; m
= memlist
)
262 pthread_mutex_unlock (&mem_mutex
);
272 pthread_mutex_lock (&mem_mutex
);
274 for (m
= memlist
; m
; m
= m
->next
)
276 fprintf (stderr
, "%s: %p %u\n", __FUNCTION__
, m
->ptr
, m
->size
);
281 "Total unfreed: %u bytes, allocations: %u, deallocations: %u\n",
282 total
, allocations
, deallocations
);
283 pthread_mutex_unlock (&mem_mutex
);