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 }