2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of libpwmd.
7 Libpwmd 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 Libpwmd 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 Libpwmd. If not, see <http://www.gnu.org/licenses/>.
35 #define _(msgid) gettext(msgid)
43 #define BACKTRACE(fn) { \
47 nptrs = backtrace(buffer, 20); \
48 strings = backtrace_symbols(buffer, nptrs); \
49 for (n = 0; n < nptrs; n++) \
50 fprintf(stderr, "BACKTRACE (%s) %i: %s\n", fn, n, strings[n]); \
51 fprintf(stderr, "\n"); \
62 #ifdef USE_PTH_THREADS
69 #define _ gettext(msgid)
76 struct memlist_s
*next
;
79 static struct memlist_s
*memlist
;
80 #ifdef USE_PTH_THREADS
81 static pth_mutex_t mem_mutex
;
83 static pthread_mutex_t mem_mutex
;
86 static size_t allocations
, deallocations
;
95 #ifdef USE_PTH_THREADS
96 pth_mutex_init (&mem_mutex
);
98 pthread_mutex_init (&mem_mutex
, NULL
);
105 memlist_remove (void *ptr
, const char *func
)
107 struct memlist_s
*m
, *last
= NULL
, *p
;
109 #ifdef USE_PTH_THREADS
110 pth_mutex_acquire (&mem_mutex
, 0, NULL
);
112 pthread_mutex_lock (&mem_mutex
);
115 for (m
= memlist
; m
; m
= m
->next
)
120 fprintf (stderr
, "%s: %p %i\n", func
, ptr
, m
->size
);
122 memzero (m
->ptr
, m
->size
);
136 #ifdef USE_PTH_THREADS
137 pth_mutex_release (&mem_mutex
);
139 pthread_mutex_unlock (&mem_mutex
);
147 #ifdef USE_PTH_THREADS
148 pth_mutex_release (&mem_mutex
);
150 pthread_mutex_unlock (&mem_mutex
);
156 memlist_prepend (struct memlist_s
*new)
158 #ifdef USE_PTH_THREADS
159 pth_mutex_acquire (&mem_mutex
, 0, NULL
);
161 pthread_mutex_lock (&mem_mutex
);
168 #ifdef USE_PTH_THREADS
169 pth_mutex_release (&mem_mutex
);
171 pthread_mutex_unlock (&mem_mutex
);
181 if (!memlist_remove (ptr
, __FUNCTION__
))
183 warnx (_("%s: %p not found"), __FUNCTION__
, ptr
);
189 _xmalloc (size_t size
)
194 if ((m
= (struct memlist_s
*) malloc (sizeof (struct memlist_s
))) == NULL
)
197 if ((p
= (void *) malloc (size
)) == NULL
)
207 fprintf (stderr
, "%s: %p %i\n", __FUNCTION__
, p
, size
);
208 BACKTRACE (__FUNCTION__
);
214 _xcalloc (size_t nmemb
, size_t size
)
219 if ((m
= (struct memlist_s
*) malloc (sizeof (struct memlist_s
))) == NULL
)
222 if ((p
= calloc (nmemb
, size
)) == NULL
)
229 m
->size
= nmemb
* size
;
232 fprintf (stderr
, "%s: %p %i\n", __FUNCTION__
, p
, nmemb
* size
);
233 BACKTRACE (__FUNCTION__
);
239 _xrealloc (void *ptr
, size_t size
)
251 return _xmalloc (size
);
253 #ifdef USE_PTH_THREADS
254 pth_mutex_acquire (&mem_mutex
, 0, NULL
);
256 pthread_mutex_lock (&mem_mutex
);
259 for (m
= memlist
; m
; m
= m
->next
)
263 if ((p
= (void *) malloc (size
)) == NULL
)
265 #ifdef USE_PTH_THREADS
266 pth_mutex_release (&mem_mutex
);
268 pthread_mutex_unlock (&mem_mutex
);
273 memcpy (p
, m
->ptr
, size
< m
->size
? size
: m
->size
);
274 memzero (m
->ptr
, m
->size
);
279 fprintf (stderr
, "%s: %p %i\n", __FUNCTION__
, p
, size
);
280 BACKTRACE (__FUNCTION__
);
282 #ifdef USE_PTH_THREADS
283 pth_mutex_release (&mem_mutex
);
285 pthread_mutex_unlock (&mem_mutex
);
291 warnx (_("%s: %p not found"), __FUNCTION__
, ptr
);
292 #ifdef USE_PTH_THREADS
293 pth_mutex_release (&mem_mutex
);
295 pthread_mutex_unlock (&mem_mutex
);
306 #ifdef USE_PTH_THREADS
307 pth_mutex_acquire (&mem_mutex
, 0, NULL
);
309 pthread_mutex_lock (&mem_mutex
);
312 for (m
= memlist
; m
; m
= memlist
)
315 #ifdef USE_PTH_THREADS
316 pth_mutex_release (&mem_mutex
);
318 pthread_mutex_unlock (&mem_mutex
);
329 #ifdef USE_PTH_THREADS
330 pth_mutex_acquire (&mem_mutex
, 0, NULL
);
332 pthread_mutex_lock (&mem_mutex
);
335 for (m
= memlist
; m
; m
= m
->next
)
337 fprintf (stderr
, "%s: %p %i\n", __FUNCTION__
, m
->ptr
, m
->size
);
342 "Total unfreed: %i bytes, allocations: %i, deallocations: %i\n",
343 total
, allocations
, deallocations
);
344 #ifdef USE_PTH_THREADS
345 pth_mutex_release (&mem_mutex
);
347 pthread_mutex_unlock (&mem_mutex
);