2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
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/>.
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)
75 struct memlist_s
*next
;
78 static struct memlist_s
*memlist
;
79 #ifdef USE_PTH_THREADS
80 static pth_mutex_t mem_mutex
;
82 static pthread_mutex_t mem_mutex
;
85 static size_t allocations
, deallocations
;
93 #ifdef USE_PTH_THREADS
94 pth_mutex_init(&mem_mutex
);
96 pthread_mutex_init(&mem_mutex
, NULL
);
102 static int memlist_remove(void *ptr
, const char *func
)
104 struct memlist_s
*m
, *last
= NULL
, *p
;
106 #ifdef USE_PTH_THREADS
107 pth_mutex_acquire(&mem_mutex
, 0, NULL
);
109 pthread_mutex_lock(&mem_mutex
);
112 for (m
= memlist
; m
; m
= m
->next
) {
115 fprintf(stderr
, "%s: %p %i\n", func
, ptr
, m
->size
);
117 memzero(m
->ptr
, m
->size
);
131 #ifdef USE_PTH_THREADS
132 pth_mutex_release(&mem_mutex
);
134 pthread_mutex_unlock(&mem_mutex
);
142 #ifdef USE_PTH_THREADS
143 pth_mutex_release(&mem_mutex
);
145 pthread_mutex_unlock(&mem_mutex
);
150 static void memlist_prepend(struct memlist_s
*new)
152 #ifdef USE_PTH_THREADS
153 pth_mutex_acquire(&mem_mutex
, 0, NULL
);
155 pthread_mutex_lock(&mem_mutex
);
162 #ifdef USE_PTH_THREADS
163 pth_mutex_release(&mem_mutex
);
165 pthread_mutex_unlock(&mem_mutex
);
169 void xfree(void *ptr
)
174 if (!memlist_remove(ptr
, __FUNCTION__
)) {
175 warnx(_("%s: %p not found"), __FUNCTION__
, ptr
);
180 void *xmalloc(size_t size
)
185 if ((m
= (struct memlist_s
*)malloc(sizeof(struct memlist_s
))) == NULL
)
188 if ((p
= (void *)malloc(size
)) == NULL
) {
197 fprintf(stderr
, "%s: %p %i\n", __FUNCTION__
, p
, size
);
198 BACKTRACE(__FUNCTION__
);
203 void *xcalloc(size_t nmemb
, size_t size
)
208 if ((m
= (struct memlist_s
*)malloc(sizeof(struct memlist_s
))) == NULL
)
211 if ((p
= calloc(nmemb
, size
)) == NULL
) {
217 m
->size
= nmemb
* size
;
220 fprintf(stderr
, "%s: %p %i\n", __FUNCTION__
, p
, nmemb
* size
);
221 BACKTRACE(__FUNCTION__
);
226 void *xrealloc(void *ptr
, size_t size
)
237 return xmalloc(size
);
239 #ifdef USE_PTH_THREADS
240 pth_mutex_acquire(&mem_mutex
, 0, NULL
);
242 pthread_mutex_lock(&mem_mutex
);
245 for (m
= memlist
; m
; m
= m
->next
) {
247 if ((p
= (void *)malloc(size
)) == NULL
) {
248 #ifdef USE_PTH_THREADS
249 pth_mutex_release(&mem_mutex
);
251 pthread_mutex_unlock(&mem_mutex
);
256 memcpy(p
, m
->ptr
, size
< m
->size
? size
: m
->size
);
257 memzero(m
->ptr
, m
->size
);
262 fprintf(stderr
, "%s: %p %i\n", __FUNCTION__
, p
, size
);
263 BACKTRACE(__FUNCTION__
);
265 #ifdef USE_PTH_THREADS
266 pth_mutex_release(&mem_mutex
);
268 pthread_mutex_unlock(&mem_mutex
);
274 warnx(_("%s: %p not found"), __FUNCTION__
, ptr
);
275 #ifdef USE_PTH_THREADS
276 pth_mutex_release(&mem_mutex
);
278 pthread_mutex_unlock(&mem_mutex
);
288 #ifdef USE_PTH_THREADS
289 pth_mutex_acquire(&mem_mutex
, 0, NULL
);
291 pthread_mutex_lock(&mem_mutex
);
294 for (m
= memlist
; m
; m
= memlist
)
297 #ifdef USE_PTH_THREADS
298 pth_mutex_release(&mem_mutex
);
300 pthread_mutex_unlock(&mem_mutex
);
310 #ifdef USE_PTH_THREADS
311 pth_mutex_acquire(&mem_mutex
, 0, NULL
);
313 pthread_mutex_lock(&mem_mutex
);
316 for (m
= memlist
; m
; m
= m
->next
) {
317 fprintf(stderr
, "%s: %p %i\n", __FUNCTION__
, m
->ptr
, m
->size
);
321 fprintf(stderr
, "Total unfreed: %i bytes, allocations: %i, deallocations: %i\n", total
,
322 allocations
, deallocations
);
323 #ifdef USE_PTH_THREADS
324 pth_mutex_release(&mem_mutex
);
326 pthread_mutex_unlock(&mem_mutex
);