zalloc_malloc.c revision 39665
1/*
2 * This module derived from code donated to the FreeBSD Project by
3 * Matthew Dillon <dillon@backplane.com>
4 *
5 * Copyright (c) 1998 The FreeBSD Project
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 *	$Id$
30 */
31
32/*
33 * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
34 */
35
36#include "zalloc_defs.h"
37
38static MemPool	MallocPool = INITPOOL("malloc", panic, znot);
39
40#ifdef DMALLOCDEBUG
41static int MallocMax;
42static int MallocCount;
43
44void mallocstats(void);
45#endif
46
47void *
48malloc(size_t bytes)
49{
50    Guard *res;
51
52#ifdef USEENDGUARD
53    bytes += MALLOCALIGN + 1;
54#else
55    bytes += MALLOCALIGN;
56#endif
57
58    while ((res = znalloc(&MallocPool, bytes)) == NULL) {
59	int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
60	char *base;
61
62	if ((base = sbrk(incr)) == (char *)-1)
63	    return(NULL);
64	zextendPool(&MallocPool, base, incr);
65	zfree(&MallocPool, base, incr);
66    }
67#ifdef DMALLOCDEBUG
68    if (++MallocCount > MallocMax)
69	MallocMax = MallocCount;
70#endif
71#ifdef USEGUARD
72    res->ga_Magic = GAMAGIC;
73#endif
74    res->ga_Bytes = bytes;
75#ifdef USEENDGUARD
76    *((char *)res + bytes - 1) = -2;
77#endif
78    return((char *)res + MALLOCALIGN);
79}
80
81void
82free(void *ptr)
83{
84    size_t bytes;
85
86    if (ptr != NULL) {
87	Guard *res = (void *)((char *)ptr - MALLOCALIGN);
88
89#ifdef USEGUARD
90	if (res->ga_Magic != GAMAGIC) {
91#ifdef USEPANIC
92	    panic("free(): guard1 fail @ %08lx\n", ptr);
93#else
94	    *(char *)0 = 1;
95#endif
96	}
97	res->ga_Magic = -1;
98#endif
99#ifdef USEENDGUARD
100	if (*((char *)res + res->ga_Bytes - 1) != -2) {
101#ifdef USEPANIC
102	    panic("free(): guard2 fail @ %08lx + %d\n", ptr, res->ga_Bytes - MALLOCALIGN);
103#else
104	    *(char *)0 = 1;
105#endif
106	}
107	*((char *)res + res->ga_Bytes - 1) = -1;
108#endif
109
110	bytes = res->ga_Bytes;
111	zfree(&MallocPool, res, bytes);
112#ifdef DMALLOCDEBUG
113	--MallocCount;
114#endif
115    }
116}
117
118
119void *
120calloc(size_t n1, size_t n2)
121{
122    iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
123    void *res;
124
125    if ((res = malloc(bytes)) != NULL) {
126	bzero(res, bytes);
127#ifdef DMALLOCDEBUG
128	if (++MallocCount > MallocMax)
129	    MallocMax = MallocCount;
130#endif
131    }
132    return(res);
133}
134
135/*
136 * realloc() - I could be fancier here and free the old buffer before
137 * 	       allocating the new one (saving potential fragmentation
138 *	       and potential buffer copies).  But I don't bother.
139 */
140
141void *
142realloc(void *ptr, size_t size)
143{
144    void *res;
145    size_t old;
146
147    if ((res = malloc(size)) != NULL) {
148	if (ptr) {
149	    old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
150	    if (old < size)
151		bcopy(ptr, res, old);
152	    else
153		bcopy(ptr, res, size);
154	    free(ptr);
155	} else {
156#ifdef DMALLOCDEBUG
157	    if (++MallocCount > MallocMax)
158		MallocMax = MallocCount;
159#ifdef EXITSTATS
160	    if (DidAtExit == 0) {
161		DidAtExit = 1;
162		atexit(mallocstats);
163	    }
164#endif
165#endif
166	}
167    }
168    return(res);
169}
170
171void *
172reallocf(void *ptr, size_t size)
173{
174    void *res;
175
176    if ((res = realloc(ptr, size)) == NULL)
177	free(ptr);
178    return(res);
179}
180
181#ifdef DMALLOCDEBUG
182
183void
184mallocstats(void)
185{
186    printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
187#ifdef ZALLOCDEBUG
188    zallocstats(&MallocPool);
189#endif
190}
191
192#endif
193
194