Mercurial > repo
comparison src/ploki/xmalloc.c @ 4223:ac0403686959
<oerjan> rm -rf src/ploki; mv ploki src
author | HackBot |
---|---|
date | Fri, 20 Dec 2013 22:18:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4222:b0f3e267bb1e | 4223:ac0403686959 |
---|---|
1 #include "config.h" | |
2 #include "main.h" | |
3 #include "xmalloc.h" | |
4 | |
5 #include <assert.h> | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 #include <errno.h> | |
10 | |
11 #ifdef DEBUG_MALLOC | |
12 #define IF_DB(x) x | |
13 #else | |
14 #define IF_DB(x) | |
15 #endif | |
16 | |
17 static struct node { | |
18 void *ptr; | |
19 struct node *prev, *next; | |
20 size_t size; | |
21 #if DEBUG_P | |
22 const char *file; | |
23 unsigned line; | |
24 #endif | |
25 } *Root; | |
26 | |
27 #if 0 | |
28 int xdump(void) { | |
29 struct node *p; | |
30 | |
31 fprintf(stderr, ":%p\n", Root); | |
32 for (p = Root; p; p = p->next) { | |
33 fprintf(stderr, "\\<%p [%p]%p %p>\n", p->prev, p, p->ptr, p->next); | |
34 assert(p != p->next); | |
35 } | |
36 fprintf(stderr, "\n"); | |
37 return 0; | |
38 } | |
39 #endif | |
40 | |
41 void xend(void) { | |
42 struct node *p; | |
43 | |
44 while ((p = Root)) { | |
45 #if DEBUG_P | |
46 unsigned char *ptr; | |
47 for (ptr = p->ptr; memcmp(ptr, &p, sizeof p); ++ptr) | |
48 ; | |
49 ptr += sizeof p; | |
50 fprintf(stderr, "%s: autofreeing pointer %p (%p) from %s:%u\n", Prog, p->ptr, (void *)ptr, p->file, p->line); | |
51 #else | |
52 fprintf(stderr, "%s: autofreeing pointer %p\n", Prog, p->ptr); | |
53 #endif | |
54 free(p->ptr); | |
55 assert(Root != p->next); | |
56 Root = p->next; | |
57 free(p); | |
58 } | |
59 } | |
60 | |
61 #define XFACTOR(size) ((sizeof (struct node *) - 1) / (size) + 1u) | |
62 | |
63 #if DEBUG_P | |
64 void *(xrealloc)(void *optr, size_t nmemb, const char *file, unsigned line) { | |
65 #else | |
66 void *xrealloc(void *optr, size_t nmemb) { | |
67 #endif | |
68 struct node *p; | |
69 size_t k; | |
70 size_t size; | |
71 unsigned char *r; | |
72 void *ptr; | |
73 | |
74 assert(optr != NULL); | |
75 | |
76 memcpy(&p, (unsigned char *)optr - sizeof Root, sizeof p); | |
77 size = p->size; | |
78 k = XFACTOR(size) * size; | |
79 if (!(ptr = realloc(p->ptr, size * nmemb + k))) { | |
80 fprintf(stderr, "%s: realloc(%p, %lu): %s\n", Prog, ptr, (unsigned long)(nmemb * size), strerror(errno)); | |
81 abort(); | |
82 } | |
83 r = (unsigned char *)ptr + k; | |
84 #if DEBUG_P | |
85 IF_DB(fprintf(stderr, "%s: xrealloc(%zu): %p (%p) from %s:%u -> %p (%p) from %s:%u\n", Prog, nmemb, p->ptr, optr, p->file, p->line, ptr, r, file, line)); | |
86 p->file = file; | |
87 p->line = line; | |
88 #endif | |
89 p->ptr = ptr; | |
90 return r; | |
91 } | |
92 | |
93 #if DEBUG_P | |
94 void *(xmalloc)(size_t nmemb, size_t size, const char *file, unsigned line) { | |
95 #else | |
96 void *xmalloc(size_t nmemb, size_t size) { | |
97 #endif | |
98 struct node *p; | |
99 size_t k; | |
100 unsigned char *r; | |
101 | |
102 if ((p = malloc(sizeof *p))) { | |
103 k = XFACTOR(size) * size; | |
104 if (!(p->ptr = malloc(size * nmemb + k))) { | |
105 free(p); | |
106 goto failure; | |
107 } | |
108 } else failure: { | |
109 fprintf(stderr, "%s: malloc(%lu): %s\n", Prog, (unsigned long)(nmemb * size), strerror(errno)); | |
110 abort(); | |
111 } | |
112 #if DEBUG_P | |
113 memset(p->ptr, 'U', k); | |
114 #endif | |
115 r = (unsigned char *)p->ptr + k; | |
116 memcpy(r - sizeof Root, &p, sizeof p); | |
117 p->size = size; | |
118 p->prev = NULL; | |
119 p->next = Root; | |
120 #if DEBUG_P | |
121 p->file = file; | |
122 p->line = line; | |
123 IF_DB(fprintf(stderr, "%s: xmalloc(%zu, %zu): %p (%p) from %s:%u\n", Prog, nmemb, size, p->ptr, r, file, line)); | |
124 #endif | |
125 if (Root) { | |
126 Root->prev = p; | |
127 } | |
128 Root = p; | |
129 return r; | |
130 } | |
131 | |
132 #if 0 | |
133 #if DEBUG_P | |
134 void *(xcalloc)(size_t nmemb, size_t size, const char *file, unsigned line) { | |
135 void *const p = xmalloc(nmemb, size, file, line); | |
136 #else | |
137 void *xcalloc(size_t nmemb, size_t size) { | |
138 void *const p = xmalloc(nmemb, size); | |
139 #endif | |
140 memset(p, '\0', nmemb * size); | |
141 return p; | |
142 } | |
143 #endif | |
144 | |
145 void xfree(void *ptr) { | |
146 struct node *p; | |
147 | |
148 if (!ptr) | |
149 return; | |
150 memcpy(&p, (unsigned char *)ptr - sizeof Root, sizeof p); | |
151 assert(p != NULL); | |
152 DEBUG(memset((unsigned char *)ptr - sizeof Root, 'F', sizeof Root)); | |
153 | |
154 if (p->next) { | |
155 p->next->prev = p->prev; | |
156 } | |
157 if (p->prev) { | |
158 p->prev->next = p->next; | |
159 } else { | |
160 assert(p == Root); | |
161 Root = Root->next; | |
162 } | |
163 #if DEBUG_P | |
164 IF_DB(fprintf(stderr, "%s: xfree(): %p (%p) from %s:%u\n", Prog, p->ptr, ptr, p->file, p->line)); | |
165 #endif | |
166 free(p->ptr); | |
167 free(p); | |
168 } |