zalloc_malloc.c revision 39863
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: zalloc_malloc.c,v 1.2 1998/09/26 10:48:50 dfr Exp $
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;
39
40#ifdef DMALLOCDEBUG
41static int MallocMax;
42static int MallocCount;
43
44void mallocstats(void);
45#endif
46
47#ifdef malloc
48#undef malloc
49#undef free
50#endif
51
52void *
53malloc(size_t bytes)
54{
55    Guard *res;
56
57#ifdef USEENDGUARD
58    bytes += MALLOCALIGN + 1;
59#else
60    bytes += MALLOCALIGN;
61#endif
62
63    while ((res = znalloc(&MallocPool, bytes)) == NULL) {
64	int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
65	char *base;
66
67	if ((base = sbrk(incr)) == (char *)-1)
68	    return(NULL);
69	zextendPool(&MallocPool, base, incr);
70	zfree(&MallocPool, base, incr);
71    }
72#ifdef DMALLOCDEBUG
73    if (++MallocCount > MallocMax)
74	MallocMax = MallocCount;
75#endif
76#ifdef USEGUARD
77    res->ga_Magic = GAMAGIC;
78#endif
79    res->ga_Bytes = bytes;
80#ifdef USEENDGUARD
81    *((char *)res + bytes - 1) = -2;
82#endif
83    return((char *)res + MALLOCALIGN);
84}
85
86void
87free(void *ptr)
88{
89    size_t bytes;
90
91    if (ptr != NULL) {
92	Guard *res = (void *)((char *)ptr - MALLOCALIGN);
93
94#ifdef USEGUARD
95	if (res->ga_Magic != GAMAGIC)
96	    panic("free: guard1 fail @ %p", ptr);
97	res->ga_Magic = -1;
98#endif
99#ifdef USEENDGUARD
100	if (*((char *)res + res->ga_Bytes - 1) != -2)
101	    panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN);
102	*((char *)res + res->ga_Bytes - 1) = -1;
103#endif
104
105	bytes = res->ga_Bytes;
106	zfree(&MallocPool, res, bytes);
107#ifdef DMALLOCDEBUG
108	--MallocCount;
109#endif
110    }
111}
112
113
114void *
115calloc(size_t n1, size_t n2)
116{
117    iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
118    void *res;
119
120    if ((res = malloc(bytes)) != NULL) {
121	bzero(res, bytes);
122#ifdef DMALLOCDEBUG
123	if (++MallocCount > MallocMax)
124	    MallocMax = MallocCount;
125#endif
126    }
127    return(res);
128}
129
130/*
131 * realloc() - I could be fancier here and free the old buffer before
132 * 	       allocating the new one (saving potential fragmentation
133 *	       and potential buffer copies).  But I don't bother.
134 */
135
136void *
137realloc(void *ptr, size_t size)
138{
139    void *res;
140    size_t old;
141
142    if ((res = malloc(size)) != NULL) {
143	if (ptr) {
144	    old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
145	    if (old < size)
146		bcopy(ptr, res, old);
147	    else
148		bcopy(ptr, res, size);
149	    free(ptr);
150	} else {
151#ifdef DMALLOCDEBUG
152	    if (++MallocCount > MallocMax)
153		MallocMax = MallocCount;
154#ifdef EXITSTATS
155	    if (DidAtExit == 0) {
156		DidAtExit = 1;
157		atexit(mallocstats);
158	    }
159#endif
160#endif
161	}
162    }
163    return(res);
164}
165
166void *
167reallocf(void *ptr, size_t size)
168{
169    void *res;
170
171    if ((res = realloc(ptr, size)) == NULL)
172	free(ptr);
173    return(res);
174}
175
176#ifdef DMALLOCDEBUG
177
178void
179mallocstats(void)
180{
181    printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
182#ifdef ZALLOCDEBUG
183    zallocstats(&MallocPool);
184#endif
185}
186
187#endif
188
189