2 * ZALLOC.C - Memory management functions
4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
12 /*NOT MPSAFE #define INTERNAL_SLABBER */
21 zalloc_norm(uintptr_t bytes)
25 #ifdef INTERNAL_SLABBER
28 } else if (bytes < SLABALLOC_ZONE_LIMIT) {
29 ptr = slab_alloc(bytes);
32 ptr = runevalloc(bytes);
36 ptr = calloc(1, bytes);
42 znalloc_norm(uintptr_t bytes)
46 #ifdef INTERNAL_SLABBER
49 } else if (bytes < SLABALLOC_ZONE_LIMIT) {
50 ptr = slab_alloc(bytes);
52 ptr = runevalloc(bytes);
61 zrealloc_norm(void *optr, uintptr_t obytes, uintptr_t nbytes)
65 #ifdef INTERNAL_SLABBER
66 if (obytes == nbytes) {
68 } else if (obytes == 0) {
69 nptr = zalloc_norm(nbytes);
70 #ifdef HAVE_SLAB_REALLOC
71 } else if (obytes < SLABALLOC_ZONE_LIMIT &&
72 nbytes < SLABALLOC_ZONE_LIMIT) {
73 nptr = slab_realloc(optr, obytes, nbytes);
75 bzero((char *)nptr + obytes, nbytes - obytes);
78 nptr = znalloc_norm(nbytes);
79 if (nbytes > obytes) {
80 bcopy(optr, nptr, obytes);
81 bzero((char *)nptr + obytes, nbytes - obytes);
83 bcopy(optr, nptr, nbytes);
85 zfree_norm(optr, obytes);
88 nptr = realloc(optr, nbytes);
90 bzero((char *)nptr + obytes, nbytes - obytes);
96 zfree_norm(void *ptr, uintptr_t bytes)
98 #ifdef INTERNAL_SLABBER
101 else if (bytes < SLABALLOC_ZONE_LIMIT)
102 slab_free(ptr, bytes);
104 runevfree(ptr, bytes);
111 zfree_wipe_norm(void *ptr, uintptr_t bytes)
113 #ifdef INTERNAL_SLABBER
116 } else if (bytes < SLABALLOC_ZONE_LIMIT) {
118 slab_free(ptr, bytes);
120 runevfree(ptr, bytes);
127 /************************************************************************
128 * ZALLOC DEBUG SUPPORT *
129 ************************************************************************/
133 typedef struct ZRef {
134 struct ZRef *zr_Next;
142 typedef struct ZallocDebug {
150 #define ZD_MAGIC 0xFA55FF11
151 #define ZD_MAGIC_FREE 0xF566AAFF
152 #define ZD_GUARD 0x51515151
153 #define ZD_GUARDCHAR 0x51
158 #define HMASK (HSIZE - 1)
164 zref(const char *file, int line)
168 int hv = 0x23FFBBCC + line;
171 for (i = 0; file[i]; ++i)
172 hv = (hv << 5) ^ file[i] ^ (hv >> 23);
173 pzr = &ZHash[hv & HMASK];
174 while ((zr = *pzr) != NULL) {
175 if (zr->zr_Hv == hv &&
176 zr->zr_Line == line &&
177 strcmp(zr->zr_File, file) == 0
183 zr = zalloc_norm(sizeof(ZRef));
193 zalloc_dump(int sigNo)
198 snprintf(buf, sizeof(buf), "ZALLOC DUMP\n");
199 write(2, buf, strlen(buf));
201 for (i = 0; i < HSIZE; ++i) {
203 for (zr = ZHash[i]; zr; zr = zr->zr_Next) {
204 snprintf(buf, sizeof(buf),
205 "%20s %-4d cnt=%-5d ttl=%-5d\n",
211 write(2, buf, strlen(buf));
217 zalloc_debug(uintptr_t bytes, const char *file, int line)
219 ZallocDebug *zd = zalloc_norm(sizeof(ZallocDebug) + bytes + 4);
222 signal(SIGUSR2, zalloc_dump);
226 zd->zd_Bytes = bytes;
227 zd->zd_Magic = ZD_MAGIC;
228 zd->zd_Ref = zref(file, line);
229 ++zd->zd_Ref->zr_Count;
230 zd->zd_Ref->zr_Bytes += bytes;
231 zd->zd_Guard = ZD_GUARD;
232 zd->zd_Data[bytes] = ZD_GUARDCHAR;
237 zfree_debug(void *ptr, uintptr_t bytes, const char *file, int line)
239 ZallocDebug *zd = (void *)((char *)ptr -
240 offsetof(ZallocDebug, zd_Data[0]));
241 if (zd->zd_Magic != ZD_MAGIC) {
242 if (zd->zd_Magic == ZD_MAGIC_FREE)
243 dpanic("%s:%d, memory location already freed!",
246 dpanic("%s:%d, memory location is not valid!",
249 if (zd->zd_Guard != ZD_GUARD ||
250 zd->zd_Data[zd->zd_Bytes] != ZD_GUARDCHAR)
251 dpanic("%s:%d, guard character overwritten!", file, line);
252 if (zd->zd_Bytes != bytes) {
253 dpanic("%s:%d, byte count mismatch: %d/%d", file, line,
254 bytes, zd->zd_Bytes);
256 --zd->zd_Ref->zr_Count;
257 zd->zd_Ref->zr_Bytes -= zd->zd_Bytes;
258 if (zd->zd_Ref->zr_Count < 0 || zd->zd_Ref->zr_Bytes < 0)
259 dpanic("%s:%d, reference structure not sane", file, line);
260 zd->zd_Magic = ZD_MAGIC_FREE;
261 zfree_norm(zd, sizeof(ZallocDebug) + zd->zd_Bytes + 4);
265 zrealloc_debug(void *optr, uintptr_t obytes,
266 uintptr_t bytes, const char *file, int line)
270 ptr = zalloc_debug(bytes, file, line);
272 bcopy(optr, ptr, (obytes > bytes) ? bytes : obytes);
274 zfree_debug(optr, obytes, file, line);