gmalloc.c revision 1.1 1 1.1 christos /* $NetBSD: gmalloc.c,v 1.1 2016/01/13 21:42:18 christos Exp $ */
2 1.1 christos
3 1.1 christos /* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */
4 1.1 christos
5 1.1 christos #define _MALLOC_INTERNAL
6 1.1 christos
7 1.1 christos /* The malloc headers and source files from the C library follow here. */
8 1.1 christos
9 1.1 christos /* Declarations for `malloc' and friends.
10 1.1 christos Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
11 1.1 christos Written May 1989 by Mike Haertel.
12 1.1 christos
13 1.1 christos This library is free software; you can redistribute it and/or
14 1.1 christos modify it under the terms of the GNU Library General Public License as
15 1.1 christos published by the Free Software Foundation; either version 2 of the
16 1.1 christos License, or (at your option) any later version.
17 1.1 christos
18 1.1 christos This library is distributed in the hope that it will be useful,
19 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
20 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 1.1 christos Library General Public License for more details.
22 1.1 christos
23 1.1 christos You should have received a copy of the GNU Library General Public
24 1.1 christos License along with this library; see the file COPYING.LIB. If
25 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
26 1.1 christos Cambridge, MA 02139, USA.
27 1.1 christos
28 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu,
29 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */
30 1.1 christos
31 1.1 christos #ifndef _MALLOC_H
32 1.1 christos
33 1.1 christos #define _MALLOC_H 1
34 1.1 christos
35 1.1 christos #ifdef _MALLOC_INTERNAL
36 1.1 christos
37 1.1 christos #ifdef HAVE_CONFIG_H
38 1.1 christos #include <config.h>
39 1.1 christos #endif
40 1.1 christos
41 1.1 christos #if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
42 1.1 christos #include <string.h>
43 1.1 christos #else
44 1.1 christos #ifndef memset
45 1.1 christos #define memset(s, zero, n) bzero ((s), (n))
46 1.1 christos #endif
47 1.1 christos #ifndef memcpy
48 1.1 christos #define memcpy(d, s, n) bcopy ((s), (d), (n))
49 1.1 christos #endif
50 1.1 christos #endif
51 1.1 christos
52 1.1 christos #if defined (__GNU_LIBRARY__) || (defined (__STDC__) && __STDC__)
53 1.1 christos #include <limits.h>
54 1.1 christos #else
55 1.1 christos #ifndef CHAR_BIT
56 1.1 christos #define CHAR_BIT 8
57 1.1 christos #endif
58 1.1 christos #endif
59 1.1 christos
60 1.1 christos #ifdef HAVE_UNISTD_H
61 1.1 christos #include <unistd.h>
62 1.1 christos #endif
63 1.1 christos
64 1.1 christos #endif /* _MALLOC_INTERNAL. */
65 1.1 christos
66 1.1 christos
67 1.1 christos #ifdef __cplusplus
68 1.1 christos extern "C"
69 1.1 christos {
70 1.1 christos #endif
71 1.1 christos
72 1.1 christos #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
73 1.1 christos #undef __P
74 1.1 christos #define __P(args) args
75 1.1 christos #undef __ptr_t
76 1.1 christos #define __ptr_t void *
77 1.1 christos #else /* Not C++ or ANSI C. */
78 1.1 christos #undef __P
79 1.1 christos #define __P(args) ()
80 1.1 christos #undef const
81 1.1 christos #define const
82 1.1 christos #undef __ptr_t
83 1.1 christos #define __ptr_t char *
84 1.1 christos #endif /* C++ or ANSI C. */
85 1.1 christos
86 1.1 christos #if defined (__STDC__) && __STDC__
87 1.1 christos #include <stddef.h>
88 1.1 christos #define __malloc_size_t size_t
89 1.1 christos #define __malloc_ptrdiff_t ptrdiff_t
90 1.1 christos #else
91 1.1 christos #define __malloc_size_t unsigned int
92 1.1 christos #define __malloc_ptrdiff_t int
93 1.1 christos #endif
94 1.1 christos
95 1.1 christos #ifndef NULL
96 1.1 christos #define NULL 0
97 1.1 christos #endif
98 1.1 christos
99 1.1 christos
100 1.1 christos /* Allocate SIZE bytes of memory. */
101 1.1 christos extern __ptr_t malloc __P ((__malloc_size_t __size));
102 1.1 christos /* Re-allocate the previously allocated block
103 1.1 christos in __ptr_t, making the new block SIZE bytes long. */
104 1.1 christos extern __ptr_t realloc __P ((__ptr_t __ptr, __malloc_size_t __size));
105 1.1 christos /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
106 1.1 christos extern __ptr_t calloc __P ((__malloc_size_t __nmemb, __malloc_size_t __size));
107 1.1 christos /* Free a block allocated by `malloc', `realloc' or `calloc'. */
108 1.1 christos extern void free __P ((__ptr_t __ptr));
109 1.1 christos
110 1.1 christos /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
111 1.1 christos extern __ptr_t memalign __P ((__malloc_size_t __alignment,
112 1.1 christos __malloc_size_t __size));
113 1.1 christos
114 1.1 christos /* Allocate SIZE bytes on a page boundary. */
115 1.1 christos extern __ptr_t valloc __P ((__malloc_size_t __size));
116 1.1 christos
117 1.1 christos
118 1.1 christos #ifdef _MALLOC_INTERNAL
119 1.1 christos
120 1.1 christos /* The allocator divides the heap into blocks of fixed size; large
121 1.1 christos requests receive one or more whole blocks, and small requests
122 1.1 christos receive a fragment of a block. Fragment sizes are powers of two,
123 1.1 christos and all fragments of a block are the same size. When all the
124 1.1 christos fragments in a block have been freed, the block itself is freed. */
125 1.1 christos #define INT_BIT (CHAR_BIT * sizeof(int))
126 1.1 christos #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
127 1.1 christos #define BLOCKSIZE (1 << BLOCKLOG)
128 1.1 christos #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
129 1.1 christos
130 1.1 christos /* Determine the amount of memory spanned by the initial heap table
131 1.1 christos (not an absolute limit). */
132 1.1 christos #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
133 1.1 christos
134 1.1 christos /* Number of contiguous free blocks allowed to build up at the end of
135 1.1 christos memory before they will be returned to the system. */
136 1.1 christos #define FINAL_FREE_BLOCKS 8
137 1.1 christos
138 1.1 christos /* Data structure giving per-block information. */
139 1.1 christos typedef union
140 1.1 christos {
141 1.1 christos /* Heap information for a busy block. */
142 1.1 christos struct
143 1.1 christos {
144 1.1 christos /* Zero for a large (multiblock) object, or positive giving the
145 1.1 christos logarithm to the base two of the fragment size. */
146 1.1 christos int type;
147 1.1 christos union
148 1.1 christos {
149 1.1 christos struct
150 1.1 christos {
151 1.1 christos __malloc_size_t nfree; /* Free frags in a fragmented block. */
152 1.1 christos __malloc_size_t first; /* First free fragment of the block. */
153 1.1 christos } frag;
154 1.1 christos /* For a large object, in its first block, this has the number
155 1.1 christos of blocks in the object. In the other blocks, this has a
156 1.1 christos negative number which says how far back the first block is. */
157 1.1 christos __malloc_ptrdiff_t size;
158 1.1 christos } info;
159 1.1 christos } busy;
160 1.1 christos /* Heap information for a free block
161 1.1 christos (that may be the first of a free cluster). */
162 1.1 christos struct
163 1.1 christos {
164 1.1 christos __malloc_size_t size; /* Size (in blocks) of a free cluster. */
165 1.1 christos __malloc_size_t next; /* Index of next free cluster. */
166 1.1 christos __malloc_size_t prev; /* Index of previous free cluster. */
167 1.1 christos } free;
168 1.1 christos } malloc_info;
169 1.1 christos
170 1.1 christos /* Pointer to first block of the heap. */
171 1.1 christos extern char *_heapbase;
172 1.1 christos
173 1.1 christos /* Table indexed by block number giving per-block information. */
174 1.1 christos extern malloc_info *_heapinfo;
175 1.1 christos
176 1.1 christos /* Address to block number and vice versa. */
177 1.1 christos #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
178 1.1 christos #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase))
179 1.1 christos
180 1.1 christos /* Current search index for the heap table. */
181 1.1 christos extern __malloc_size_t _heapindex;
182 1.1 christos
183 1.1 christos /* Limit of valid info table indices. */
184 1.1 christos extern __malloc_size_t _heaplimit;
185 1.1 christos
186 1.1 christos /* Doubly linked lists of free fragments. */
187 1.1 christos struct list
188 1.1 christos {
189 1.1 christos struct list *next;
190 1.1 christos struct list *prev;
191 1.1 christos };
192 1.1 christos
193 1.1 christos /* Free list headers for each fragment size. */
194 1.1 christos extern struct list _fraghead[];
195 1.1 christos
196 1.1 christos /* List of blocks allocated with `memalign' (or `valloc'). */
197 1.1 christos struct alignlist
198 1.1 christos {
199 1.1 christos struct alignlist *next;
200 1.1 christos __ptr_t aligned; /* The address that memaligned returned. */
201 1.1 christos __ptr_t exact; /* The address that malloc returned. */
202 1.1 christos };
203 1.1 christos extern struct alignlist *_aligned_blocks;
204 1.1 christos
205 1.1 christos /* Instrumentation. */
206 1.1 christos extern __malloc_size_t _chunks_used;
207 1.1 christos extern __malloc_size_t _bytes_used;
208 1.1 christos extern __malloc_size_t _chunks_free;
209 1.1 christos extern __malloc_size_t _bytes_free;
210 1.1 christos
211 1.1 christos /* Internal version of `free' used in `morecore' (malloc.c). */
212 1.1 christos extern void _free_internal __P ((__ptr_t __ptr));
213 1.1 christos
214 1.1 christos #endif /* _MALLOC_INTERNAL. */
215 1.1 christos
216 1.1 christos /* Given an address in the middle of a malloc'd object,
217 1.1 christos return the address of the beginning of the object. */
218 1.1 christos extern __ptr_t malloc_find_object_address __P ((__ptr_t __ptr));
219 1.1 christos
220 1.1 christos /* Underlying allocation function; successive calls should
221 1.1 christos return contiguous pieces of memory. */
222 1.1 christos extern __ptr_t (*__morecore) __P ((__malloc_ptrdiff_t __size));
223 1.1 christos
224 1.1 christos /* Default value of `__morecore'. */
225 1.1 christos extern __ptr_t __default_morecore __P ((__malloc_ptrdiff_t __size));
226 1.1 christos
227 1.1 christos /* If not NULL, this function is called after each time
228 1.1 christos `__morecore' is called to increase the data size. */
229 1.1 christos extern void (*__after_morecore_hook) __P ((void));
230 1.1 christos
231 1.1 christos /* Nonzero if `malloc' has been called and done its initialization. */
232 1.1 christos extern int __malloc_initialized;
233 1.1 christos
234 1.1 christos /* Hooks for debugging versions. */
235 1.1 christos extern void (*__malloc_initialize_hook) __P ((void));
236 1.1 christos extern void (*__free_hook) __P ((__ptr_t __ptr));
237 1.1 christos extern __ptr_t (*__malloc_hook) __P ((__malloc_size_t __size));
238 1.1 christos extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size));
239 1.1 christos extern __ptr_t (*__memalign_hook) __P ((__malloc_size_t __size,
240 1.1 christos __malloc_size_t __alignment));
241 1.1 christos
242 1.1 christos /* Return values for `mprobe': these are the kinds of inconsistencies that
243 1.1 christos `mcheck' enables detection of. */
244 1.1 christos enum mcheck_status
245 1.1 christos {
246 1.1 christos MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
247 1.1 christos MCHECK_OK, /* Block is fine. */
248 1.1 christos MCHECK_FREE, /* Block freed twice. */
249 1.1 christos MCHECK_HEAD, /* Memory before the block was clobbered. */
250 1.1 christos MCHECK_TAIL /* Memory after the block was clobbered. */
251 1.1 christos };
252 1.1 christos
253 1.1 christos /* Activate a standard collection of debugging hooks. This must be called
254 1.1 christos before `malloc' is ever called. ABORTFUNC is called with an error code
255 1.1 christos (see enum above) when an inconsistency is detected. If ABORTFUNC is
256 1.1 christos null, the standard function prints on stderr and then calls `abort'. */
257 1.1 christos extern int mcheck __P ((void (*__abortfunc) __P ((enum mcheck_status))));
258 1.1 christos
259 1.1 christos /* Check for aberrations in a particular malloc'd block. You must have
260 1.1 christos called `mcheck' already. These are the same checks that `mcheck' does
261 1.1 christos when you free or reallocate a block. */
262 1.1 christos extern enum mcheck_status mprobe __P ((__ptr_t __ptr));
263 1.1 christos
264 1.1 christos /* Activate a standard collection of tracing hooks. */
265 1.1 christos extern void mtrace __P ((void));
266 1.1 christos extern void muntrace __P ((void));
267 1.1 christos
268 1.1 christos /* Statistics available to the user. */
269 1.1 christos struct mstats
270 1.1 christos {
271 1.1 christos __malloc_size_t bytes_total; /* Total size of the heap. */
272 1.1 christos __malloc_size_t chunks_used; /* Chunks allocated by the user. */
273 1.1 christos __malloc_size_t bytes_used; /* Byte total of user-allocated chunks. */
274 1.1 christos __malloc_size_t chunks_free; /* Chunks in the free list. */
275 1.1 christos __malloc_size_t bytes_free; /* Byte total of chunks in the free list. */
276 1.1 christos };
277 1.1 christos
278 1.1 christos /* Pick up the current statistics. */
279 1.1 christos extern struct mstats mstats __P ((void));
280 1.1 christos
281 1.1 christos /* Call WARNFUN with a warning message when memory usage is high. */
282 1.1 christos extern void memory_warnings __P ((__ptr_t __start,
283 1.1 christos void (*__warnfun) __P ((const char *))));
284 1.1 christos
285 1.1 christos
286 1.1 christos /* Relocating allocator. */
287 1.1 christos
288 1.1 christos /* Allocate SIZE bytes, and store the address in *HANDLEPTR. */
289 1.1 christos extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, __malloc_size_t __size));
290 1.1 christos
291 1.1 christos /* Free the storage allocated in HANDLEPTR. */
292 1.1 christos extern void r_alloc_free __P ((__ptr_t *__handleptr));
293 1.1 christos
294 1.1 christos /* Adjust the block at HANDLEPTR to be SIZE bytes long. */
295 1.1 christos extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, __malloc_size_t __size));
296 1.1 christos
297 1.1 christos
298 1.1 christos #ifdef __cplusplus
299 1.1 christos }
300 1.1 christos #endif
301 1.1 christos
302 1.1 christos #endif /* malloc.h */
303 1.1 christos /* Allocate memory on a page boundary.
304 1.1 christos Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
305 1.1 christos
306 1.1 christos This library is free software; you can redistribute it and/or
307 1.1 christos modify it under the terms of the GNU Library General Public License as
308 1.1 christos published by the Free Software Foundation; either version 2 of the
309 1.1 christos License, or (at your option) any later version.
310 1.1 christos
311 1.1 christos This library is distributed in the hope that it will be useful,
312 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
313 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
314 1.1 christos Library General Public License for more details.
315 1.1 christos
316 1.1 christos You should have received a copy of the GNU Library General Public
317 1.1 christos License along with this library; see the file COPYING.LIB. If
318 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
319 1.1 christos Cambridge, MA 02139, USA.
320 1.1 christos
321 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu,
322 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */
323 1.1 christos
324 1.1 christos #if defined (__GNU_LIBRARY__) || defined (_LIBC)
325 1.1 christos #include <stddef.h>
326 1.1 christos #include <sys/cdefs.h>
327 1.1 christos extern size_t __getpagesize __P ((void));
328 1.1 christos #else
329 1.1 christos #include "getpagesize.h"
330 1.1 christos #define __getpagesize() getpagesize()
331 1.1 christos #endif
332 1.1 christos
333 1.1 christos #ifndef _MALLOC_INTERNAL
334 1.1 christos #define _MALLOC_INTERNAL
335 1.1 christos #include <malloc.h>
336 1.1 christos #endif
337 1.1 christos
338 1.1 christos static __malloc_size_t pagesize;
339 1.1 christos
340 1.1 christos __ptr_t
341 1.1 christos valloc (size)
342 1.1 christos __malloc_size_t size;
343 1.1 christos {
344 1.1 christos if (pagesize == 0)
345 1.1 christos pagesize = __getpagesize ();
346 1.1 christos
347 1.1 christos return memalign (pagesize, size);
348 1.1 christos }
349 1.1 christos /* Memory allocator `malloc'.
350 1.1 christos Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
351 1.1 christos Written May 1989 by Mike Haertel.
352 1.1 christos
353 1.1 christos This library is free software; you can redistribute it and/or
354 1.1 christos modify it under the terms of the GNU Library General Public License as
355 1.1 christos published by the Free Software Foundation; either version 2 of the
356 1.1 christos License, or (at your option) any later version.
357 1.1 christos
358 1.1 christos This library is distributed in the hope that it will be useful,
359 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
360 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
361 1.1 christos Library General Public License for more details.
362 1.1 christos
363 1.1 christos You should have received a copy of the GNU Library General Public
364 1.1 christos License along with this library; see the file COPYING.LIB. If
365 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
366 1.1 christos Cambridge, MA 02139, USA.
367 1.1 christos
368 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu,
369 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */
370 1.1 christos
371 1.1 christos #ifndef _MALLOC_INTERNAL
372 1.1 christos #define _MALLOC_INTERNAL
373 1.1 christos #include <malloc.h>
374 1.1 christos #endif
375 1.1 christos
376 1.1 christos /* How to really get more memory. */
377 1.1 christos __ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore;
378 1.1 christos
379 1.1 christos /* Debugging hook for `malloc'. */
380 1.1 christos __ptr_t (*__malloc_hook) __P ((__malloc_size_t __size));
381 1.1 christos
382 1.1 christos /* Pointer to the base of the first block. */
383 1.1 christos char *_heapbase;
384 1.1 christos
385 1.1 christos /* Block information table. Allocated with align/__free (not malloc/free). */
386 1.1 christos malloc_info *_heapinfo;
387 1.1 christos
388 1.1 christos /* Number of info entries. */
389 1.1 christos static __malloc_size_t heapsize;
390 1.1 christos
391 1.1 christos /* Search index in the info table. */
392 1.1 christos __malloc_size_t _heapindex;
393 1.1 christos
394 1.1 christos /* Limit of valid info table indices. */
395 1.1 christos __malloc_size_t _heaplimit;
396 1.1 christos
397 1.1 christos /* Free lists for each fragment size. */
398 1.1 christos struct list _fraghead[BLOCKLOG];
399 1.1 christos
400 1.1 christos /* Instrumentation. */
401 1.1 christos __malloc_size_t _chunks_used;
402 1.1 christos __malloc_size_t _bytes_used;
403 1.1 christos __malloc_size_t _chunks_free;
404 1.1 christos __malloc_size_t _bytes_free;
405 1.1 christos
406 1.1 christos /* Are you experienced? */
407 1.1 christos int __malloc_initialized;
408 1.1 christos
409 1.1 christos void (*__malloc_initialize_hook) __P ((void));
410 1.1 christos void (*__after_morecore_hook) __P ((void));
411 1.1 christos
412 1.1 christos /* Aligned allocation. */
413 1.1 christos static __ptr_t align __P ((__malloc_size_t));
414 1.1 christos static __ptr_t
415 1.1 christos align (size)
416 1.1 christos __malloc_size_t size;
417 1.1 christos {
418 1.1 christos __ptr_t result;
419 1.1 christos unsigned long int adj;
420 1.1 christos
421 1.1 christos result = (*__morecore) (size);
422 1.1 christos adj = (unsigned long int) ((unsigned long int) ((char *) result -
423 1.1 christos (char *) NULL)) % BLOCKSIZE;
424 1.1 christos if (adj != 0)
425 1.1 christos {
426 1.1 christos adj = BLOCKSIZE - adj;
427 1.1 christos (void) (*__morecore) (adj);
428 1.1 christos result = (char *) result + adj;
429 1.1 christos }
430 1.1 christos
431 1.1 christos if (__after_morecore_hook)
432 1.1 christos (*__after_morecore_hook) ();
433 1.1 christos
434 1.1 christos return result;
435 1.1 christos }
436 1.1 christos
437 1.1 christos /* Set everything up and remember that we have. */
438 1.1 christos static int initialize __P ((void));
439 1.1 christos static int
440 1.1 christos initialize ()
441 1.1 christos {
442 1.1 christos if (__malloc_initialize_hook)
443 1.1 christos (*__malloc_initialize_hook) ();
444 1.1 christos
445 1.1 christos heapsize = HEAP / BLOCKSIZE;
446 1.1 christos _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info));
447 1.1 christos if (_heapinfo == NULL)
448 1.1 christos return 0;
449 1.1 christos memset (_heapinfo, 0, heapsize * sizeof (malloc_info));
450 1.1 christos _heapinfo[0].free.size = 0;
451 1.1 christos _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
452 1.1 christos _heapindex = 0;
453 1.1 christos _heapbase = (char *) _heapinfo;
454 1.1 christos
455 1.1 christos /* Account for the _heapinfo block itself in the statistics. */
456 1.1 christos _bytes_used = heapsize * sizeof (malloc_info);
457 1.1 christos _chunks_used = 1;
458 1.1 christos
459 1.1 christos __malloc_initialized = 1;
460 1.1 christos return 1;
461 1.1 christos }
462 1.1 christos
463 1.1 christos /* Get neatly aligned memory, initializing or
464 1.1 christos growing the heap info table as necessary. */
465 1.1 christos static __ptr_t morecore __P ((__malloc_size_t));
466 1.1 christos static __ptr_t
467 1.1 christos morecore (size)
468 1.1 christos __malloc_size_t size;
469 1.1 christos {
470 1.1 christos __ptr_t result;
471 1.1 christos malloc_info *newinfo, *oldinfo;
472 1.1 christos __malloc_size_t newsize;
473 1.1 christos
474 1.1 christos result = align (size);
475 1.1 christos if (result == NULL)
476 1.1 christos return NULL;
477 1.1 christos
478 1.1 christos /* Check if we need to grow the info table. */
479 1.1 christos if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize)
480 1.1 christos {
481 1.1 christos newsize = heapsize;
482 1.1 christos while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize)
483 1.1 christos newsize *= 2;
484 1.1 christos newinfo = (malloc_info *) align (newsize * sizeof (malloc_info));
485 1.1 christos if (newinfo == NULL)
486 1.1 christos {
487 1.1 christos (*__morecore) (-size);
488 1.1 christos return NULL;
489 1.1 christos }
490 1.1 christos memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info));
491 1.1 christos memset (&newinfo[heapsize], 0,
492 1.1 christos (newsize - heapsize) * sizeof (malloc_info));
493 1.1 christos oldinfo = _heapinfo;
494 1.1 christos newinfo[BLOCK (oldinfo)].busy.type = 0;
495 1.1 christos newinfo[BLOCK (oldinfo)].busy.info.size
496 1.1 christos = BLOCKIFY (heapsize * sizeof (malloc_info));
497 1.1 christos _heapinfo = newinfo;
498 1.1 christos /* Account for the _heapinfo block itself in the statistics. */
499 1.1 christos _bytes_used += newsize * sizeof (malloc_info);
500 1.1 christos ++_chunks_used;
501 1.1 christos _free_internal (oldinfo);
502 1.1 christos heapsize = newsize;
503 1.1 christos }
504 1.1 christos
505 1.1 christos _heaplimit = BLOCK ((char *) result + size);
506 1.1 christos return result;
507 1.1 christos }
508 1.1 christos
509 1.1 christos /* Allocate memory from the heap. */
510 1.1 christos __ptr_t
511 1.1 christos malloc (size)
512 1.1 christos __malloc_size_t size;
513 1.1 christos {
514 1.1 christos __ptr_t result;
515 1.1 christos __malloc_size_t block, blocks, lastblocks, start;
516 1.1 christos register __malloc_size_t i;
517 1.1 christos struct list *next;
518 1.1 christos
519 1.1 christos /* ANSI C allows `malloc (0)' to either return NULL, or to return a
520 1.1 christos valid address you can realloc and free (though not dereference).
521 1.1 christos
522 1.1 christos It turns out that some extant code (sunrpc, at least Ultrix's version)
523 1.1 christos expects `malloc (0)' to return non-NULL and breaks otherwise.
524 1.1 christos Be compatible. */
525 1.1 christos
526 1.1 christos #if 0
527 1.1 christos if (size == 0)
528 1.1 christos return NULL;
529 1.1 christos #endif
530 1.1 christos
531 1.1 christos if (__malloc_hook != NULL)
532 1.1 christos return (*__malloc_hook) (size);
533 1.1 christos
534 1.1 christos if (!__malloc_initialized)
535 1.1 christos if (!initialize ())
536 1.1 christos return NULL;
537 1.1 christos
538 1.1 christos if (size < sizeof (struct list))
539 1.1 christos size = sizeof (struct list);
540 1.1 christos
541 1.1 christos #ifdef SUNOS_LOCALTIME_BUG
542 1.1 christos if (size < 16)
543 1.1 christos size = 16;
544 1.1 christos #endif
545 1.1 christos
546 1.1 christos /* Determine the allocation policy based on the request size. */
547 1.1 christos if (size <= BLOCKSIZE / 2)
548 1.1 christos {
549 1.1 christos /* Small allocation to receive a fragment of a block.
550 1.1 christos Determine the logarithm to base two of the fragment size. */
551 1.1 christos register __malloc_size_t log = 1;
552 1.1 christos --size;
553 1.1 christos while ((size /= 2) != 0)
554 1.1 christos ++log;
555 1.1 christos
556 1.1 christos /* Look in the fragment lists for a
557 1.1 christos free fragment of the desired size. */
558 1.1 christos next = _fraghead[log].next;
559 1.1 christos if (next != NULL)
560 1.1 christos {
561 1.1 christos /* There are free fragments of this size.
562 1.1 christos Pop a fragment out of the fragment list and return it.
563 1.1 christos Update the block's nfree and first counters. */
564 1.1 christos result = (__ptr_t) next;
565 1.1 christos next->prev->next = next->next;
566 1.1 christos if (next->next != NULL)
567 1.1 christos next->next->prev = next->prev;
568 1.1 christos block = BLOCK (result);
569 1.1 christos if (--_heapinfo[block].busy.info.frag.nfree != 0)
570 1.1 christos _heapinfo[block].busy.info.frag.first = (unsigned long int)
571 1.1 christos ((unsigned long int) ((char *) next->next - (char *) NULL)
572 1.1 christos % BLOCKSIZE) >> log;
573 1.1 christos
574 1.1 christos /* Update the statistics. */
575 1.1 christos ++_chunks_used;
576 1.1 christos _bytes_used += 1 << log;
577 1.1 christos --_chunks_free;
578 1.1 christos _bytes_free -= 1 << log;
579 1.1 christos }
580 1.1 christos else
581 1.1 christos {
582 1.1 christos /* No free fragments of the desired size, so get a new block
583 1.1 christos and break it into fragments, returning the first. */
584 1.1 christos result = malloc (BLOCKSIZE);
585 1.1 christos if (result == NULL)
586 1.1 christos return NULL;
587 1.1 christos
588 1.1 christos /* Link all fragments but the first into the free list. */
589 1.1 christos for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i)
590 1.1 christos {
591 1.1 christos next = (struct list *) ((char *) result + (i << log));
592 1.1 christos next->next = _fraghead[log].next;
593 1.1 christos next->prev = &_fraghead[log];
594 1.1 christos next->prev->next = next;
595 1.1 christos if (next->next != NULL)
596 1.1 christos next->next->prev = next;
597 1.1 christos }
598 1.1 christos
599 1.1 christos /* Initialize the nfree and first counters for this block. */
600 1.1 christos block = BLOCK (result);
601 1.1 christos _heapinfo[block].busy.type = log;
602 1.1 christos _heapinfo[block].busy.info.frag.nfree = i - 1;
603 1.1 christos _heapinfo[block].busy.info.frag.first = i - 1;
604 1.1 christos
605 1.1 christos _chunks_free += (BLOCKSIZE >> log) - 1;
606 1.1 christos _bytes_free += BLOCKSIZE - (1 << log);
607 1.1 christos _bytes_used -= BLOCKSIZE - (1 << log);
608 1.1 christos }
609 1.1 christos }
610 1.1 christos else
611 1.1 christos {
612 1.1 christos /* Large allocation to receive one or more blocks.
613 1.1 christos Search the free list in a circle starting at the last place visited.
614 1.1 christos If we loop completely around without finding a large enough
615 1.1 christos space we will have to get more memory from the system. */
616 1.1 christos blocks = BLOCKIFY (size);
617 1.1 christos start = block = _heapindex;
618 1.1 christos while (_heapinfo[block].free.size < blocks)
619 1.1 christos {
620 1.1 christos block = _heapinfo[block].free.next;
621 1.1 christos if (block == start)
622 1.1 christos {
623 1.1 christos /* Need to get more from the system. Check to see if
624 1.1 christos the new core will be contiguous with the final free
625 1.1 christos block; if so we don't need to get as much. */
626 1.1 christos block = _heapinfo[0].free.prev;
627 1.1 christos lastblocks = _heapinfo[block].free.size;
628 1.1 christos if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
629 1.1 christos (*__morecore) (0) == ADDRESS (block + lastblocks) &&
630 1.1 christos (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL)
631 1.1 christos {
632 1.1 christos /* Which block we are extending (the `final free
633 1.1 christos block' referred to above) might have changed, if
634 1.1 christos it got combined with a freed info table. */
635 1.1 christos block = _heapinfo[0].free.prev;
636 1.1 christos _heapinfo[block].free.size += (blocks - lastblocks);
637 1.1 christos _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
638 1.1 christos continue;
639 1.1 christos }
640 1.1 christos result = morecore (blocks * BLOCKSIZE);
641 1.1 christos if (result == NULL)
642 1.1 christos return NULL;
643 1.1 christos block = BLOCK (result);
644 1.1 christos _heapinfo[block].busy.type = 0;
645 1.1 christos _heapinfo[block].busy.info.size = blocks;
646 1.1 christos ++_chunks_used;
647 1.1 christos _bytes_used += blocks * BLOCKSIZE;
648 1.1 christos return result;
649 1.1 christos }
650 1.1 christos }
651 1.1 christos
652 1.1 christos /* At this point we have found a suitable free list entry.
653 1.1 christos Figure out how to remove what we need from the list. */
654 1.1 christos result = ADDRESS (block);
655 1.1 christos if (_heapinfo[block].free.size > blocks)
656 1.1 christos {
657 1.1 christos /* The block we found has a bit left over,
658 1.1 christos so relink the tail end back into the free list. */
659 1.1 christos _heapinfo[block + blocks].free.size
660 1.1 christos = _heapinfo[block].free.size - blocks;
661 1.1 christos _heapinfo[block + blocks].free.next
662 1.1 christos = _heapinfo[block].free.next;
663 1.1 christos _heapinfo[block + blocks].free.prev
664 1.1 christos = _heapinfo[block].free.prev;
665 1.1 christos _heapinfo[_heapinfo[block].free.prev].free.next
666 1.1 christos = _heapinfo[_heapinfo[block].free.next].free.prev
667 1.1 christos = _heapindex = block + blocks;
668 1.1 christos }
669 1.1 christos else
670 1.1 christos {
671 1.1 christos /* The block exactly matches our requirements,
672 1.1 christos so just remove it from the list. */
673 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev
674 1.1 christos = _heapinfo[block].free.prev;
675 1.1 christos _heapinfo[_heapinfo[block].free.prev].free.next
676 1.1 christos = _heapindex = _heapinfo[block].free.next;
677 1.1 christos --_chunks_free;
678 1.1 christos }
679 1.1 christos
680 1.1 christos _heapinfo[block].busy.type = 0;
681 1.1 christos _heapinfo[block].busy.info.size = blocks;
682 1.1 christos ++_chunks_used;
683 1.1 christos _bytes_used += blocks * BLOCKSIZE;
684 1.1 christos _bytes_free -= blocks * BLOCKSIZE;
685 1.1 christos
686 1.1 christos /* Mark all the blocks of the object just allocated except for the
687 1.1 christos first with a negative number so you can find the first block by
688 1.1 christos adding that adjustment. */
689 1.1 christos while (--blocks > 0)
690 1.1 christos _heapinfo[block + blocks].busy.info.size = -blocks;
691 1.1 christos }
692 1.1 christos
693 1.1 christos return result;
694 1.1 christos }
695 1.1 christos
696 1.1 christos #ifndef _LIBC
698 1.1 christos
699 1.1 christos /* On some ANSI C systems, some libc functions call _malloc, _free
700 1.1 christos and _realloc. Make them use the GNU functions. */
701 1.1 christos
702 1.1 christos __ptr_t
703 1.1 christos _malloc (size)
704 1.1 christos __malloc_size_t size;
705 1.1 christos {
706 1.1 christos return malloc (size);
707 1.1 christos }
708 1.1 christos
709 1.1 christos void
710 1.1 christos _free (ptr)
711 1.1 christos __ptr_t ptr;
712 1.1 christos {
713 1.1 christos free (ptr);
714 1.1 christos }
715 1.1 christos
716 1.1 christos __ptr_t
717 1.1 christos _realloc (ptr, size)
718 1.1 christos __ptr_t ptr;
719 1.1 christos __malloc_size_t size;
720 1.1 christos {
721 1.1 christos return realloc (ptr, size);
722 1.1 christos }
723 1.1 christos
724 1.1 christos #endif
725 1.1 christos /* Free a block of memory allocated by `malloc'.
726 1.1 christos Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
727 1.1 christos Written May 1989 by Mike Haertel.
728 1.1 christos
729 1.1 christos This library is free software; you can redistribute it and/or
730 1.1 christos modify it under the terms of the GNU Library General Public License as
731 1.1 christos published by the Free Software Foundation; either version 2 of the
732 1.1 christos License, or (at your option) any later version.
733 1.1 christos
734 1.1 christos This library is distributed in the hope that it will be useful,
735 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
736 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
737 1.1 christos Library General Public License for more details.
738 1.1 christos
739 1.1 christos You should have received a copy of the GNU Library General Public
740 1.1 christos License along with this library; see the file COPYING.LIB. If
741 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
742 1.1 christos Cambridge, MA 02139, USA.
743 1.1 christos
744 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu,
745 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */
746 1.1 christos
747 1.1 christos #ifndef _MALLOC_INTERNAL
748 1.1 christos #define _MALLOC_INTERNAL
749 1.1 christos #include <malloc.h>
750 1.1 christos #endif
751 1.1 christos
752 1.1 christos /* Debugging hook for free. */
753 1.1 christos void (*__free_hook) __P ((__ptr_t __ptr));
754 1.1 christos
755 1.1 christos /* List of blocks allocated by memalign. */
756 1.1 christos struct alignlist *_aligned_blocks = NULL;
757 1.1 christos
758 1.1 christos /* Return memory to the heap.
759 1.1 christos Like `free' but don't call a __free_hook if there is one. */
760 1.1 christos void
761 1.1 christos _free_internal (ptr)
762 1.1 christos __ptr_t ptr;
763 1.1 christos {
764 1.1 christos int type;
765 1.1 christos __malloc_size_t block, blocks;
766 1.1 christos register __malloc_size_t i;
767 1.1 christos struct list *prev, *next;
768 1.1 christos
769 1.1 christos block = BLOCK (ptr);
770 1.1 christos
771 1.1 christos type = _heapinfo[block].busy.type;
772 1.1 christos switch (type)
773 1.1 christos {
774 1.1 christos case 0:
775 1.1 christos /* Get as many statistics as early as we can. */
776 1.1 christos --_chunks_used;
777 1.1 christos _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
778 1.1 christos _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
779 1.1 christos
780 1.1 christos /* Find the free cluster previous to this one in the free list.
781 1.1 christos Start searching at the last block referenced; this may benefit
782 1.1 christos programs with locality of allocation. */
783 1.1 christos i = _heapindex;
784 1.1 christos if (i > block)
785 1.1 christos while (i > block)
786 1.1 christos i = _heapinfo[i].free.prev;
787 1.1 christos else
788 1.1 christos {
789 1.1 christos do
790 1.1 christos i = _heapinfo[i].free.next;
791 1.1 christos while (i > 0 && i < block);
792 1.1 christos i = _heapinfo[i].free.prev;
793 1.1 christos }
794 1.1 christos
795 1.1 christos /* Determine how to link this block into the free list. */
796 1.1 christos if (block == i + _heapinfo[i].free.size)
797 1.1 christos {
798 1.1 christos /* Coalesce this block with its predecessor. */
799 1.1 christos _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
800 1.1 christos block = i;
801 1.1 christos }
802 1.1 christos else
803 1.1 christos {
804 1.1 christos /* Really link this block back into the free list. */
805 1.1 christos _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
806 1.1 christos _heapinfo[block].free.next = _heapinfo[i].free.next;
807 1.1 christos _heapinfo[block].free.prev = i;
808 1.1 christos _heapinfo[i].free.next = block;
809 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev = block;
810 1.1 christos ++_chunks_free;
811 1.1 christos }
812 1.1 christos
813 1.1 christos /* Now that the block is linked in, see if we can coalesce it
814 1.1 christos with its successor (by deleting its successor from the list
815 1.1 christos and adding in its size). */
816 1.1 christos if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
817 1.1 christos {
818 1.1 christos _heapinfo[block].free.size
819 1.1 christos += _heapinfo[_heapinfo[block].free.next].free.size;
820 1.1 christos _heapinfo[block].free.next
821 1.1 christos = _heapinfo[_heapinfo[block].free.next].free.next;
822 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev = block;
823 1.1 christos --_chunks_free;
824 1.1 christos }
825 1.1 christos
826 1.1 christos /* Now see if we can return stuff to the system. */
827 1.1 christos blocks = _heapinfo[block].free.size;
828 1.1 christos if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
829 1.1 christos && (*__morecore) (0) == ADDRESS (block + blocks))
830 1.1 christos {
831 1.1 christos register __malloc_size_t bytes = blocks * BLOCKSIZE;
832 1.1 christos _heaplimit -= blocks;
833 1.1 christos (*__morecore) (-bytes);
834 1.1 christos _heapinfo[_heapinfo[block].free.prev].free.next
835 1.1 christos = _heapinfo[block].free.next;
836 1.1 christos _heapinfo[_heapinfo[block].free.next].free.prev
837 1.1 christos = _heapinfo[block].free.prev;
838 1.1 christos block = _heapinfo[block].free.prev;
839 1.1 christos --_chunks_free;
840 1.1 christos _bytes_free -= bytes;
841 1.1 christos }
842 1.1 christos
843 1.1 christos /* Set the next search to begin at this block. */
844 1.1 christos _heapindex = block;
845 1.1 christos break;
846 1.1 christos
847 1.1 christos default:
848 1.1 christos /* Do some of the statistics. */
849 1.1 christos --_chunks_used;
850 1.1 christos _bytes_used -= 1 << type;
851 1.1 christos ++_chunks_free;
852 1.1 christos _bytes_free += 1 << type;
853 1.1 christos
854 1.1 christos /* Get the address of the first free fragment in this block. */
855 1.1 christos prev = (struct list *) ((char *) ADDRESS (block) +
856 1.1 christos (_heapinfo[block].busy.info.frag.first << type));
857 1.1 christos
858 1.1 christos if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
859 1.1 christos {
860 1.1 christos /* If all fragments of this block are free, remove them
861 1.1 christos from the fragment list and free the whole block. */
862 1.1 christos next = prev;
863 1.1 christos for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i)
864 1.1 christos next = next->next;
865 1.1 christos prev->prev->next = next;
866 1.1 christos if (next != NULL)
867 1.1 christos next->prev = prev->prev;
868 1.1 christos _heapinfo[block].busy.type = 0;
869 1.1 christos _heapinfo[block].busy.info.size = 1;
870 1.1 christos
871 1.1 christos /* Keep the statistics accurate. */
872 1.1 christos ++_chunks_used;
873 1.1 christos _bytes_used += BLOCKSIZE;
874 1.1 christos _chunks_free -= BLOCKSIZE >> type;
875 1.1 christos _bytes_free -= BLOCKSIZE;
876 1.1 christos
877 1.1 christos free (ADDRESS (block));
878 1.1 christos }
879 1.1 christos else if (_heapinfo[block].busy.info.frag.nfree != 0)
880 1.1 christos {
881 1.1 christos /* If some fragments of this block are free, link this
882 1.1 christos fragment into the fragment list after the first free
883 1.1 christos fragment of this block. */
884 1.1 christos next = (struct list *) ptr;
885 1.1 christos next->next = prev->next;
886 1.1 christos next->prev = prev;
887 1.1 christos prev->next = next;
888 1.1 christos if (next->next != NULL)
889 1.1 christos next->next->prev = next;
890 1.1 christos ++_heapinfo[block].busy.info.frag.nfree;
891 1.1 christos }
892 1.1 christos else
893 1.1 christos {
894 1.1 christos /* No fragments of this block are free, so link this
895 1.1 christos fragment into the fragment list and announce that
896 1.1 christos it is the first free fragment of this block. */
897 1.1 christos prev = (struct list *) ptr;
898 1.1 christos _heapinfo[block].busy.info.frag.nfree = 1;
899 1.1 christos _heapinfo[block].busy.info.frag.first = (unsigned long int)
900 1.1 christos ((unsigned long int) ((char *) ptr - (char *) NULL)
901 1.1 christos % BLOCKSIZE >> type);
902 1.1 christos prev->next = _fraghead[type].next;
903 1.1 christos prev->prev = &_fraghead[type];
904 1.1 christos prev->prev->next = prev;
905 1.1 christos if (prev->next != NULL)
906 1.1 christos prev->next->prev = prev;
907 1.1 christos }
908 1.1 christos break;
909 1.1 christos }
910 1.1 christos }
911 1.1 christos
912 1.1 christos /* Return memory to the heap. */
913 1.1 christos void
914 1.1 christos free (ptr)
915 1.1 christos __ptr_t ptr;
916 1.1 christos {
917 1.1 christos register struct alignlist *l;
918 1.1 christos
919 1.1 christos if (ptr == NULL)
920 1.1 christos return;
921 1.1 christos
922 1.1 christos for (l = _aligned_blocks; l != NULL; l = l->next)
923 1.1 christos if (l->aligned == ptr)
924 1.1 christos {
925 1.1 christos l->aligned = NULL; /* Mark the slot in the list as free. */
926 1.1 christos ptr = l->exact;
927 1.1 christos break;
928 1.1 christos }
929 1.1 christos
930 1.1 christos if (__free_hook != NULL)
931 1.1 christos (*__free_hook) (ptr);
932 1.1 christos else
933 1.1 christos _free_internal (ptr);
934 1.1 christos }
935 1.1 christos /* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
936 1.1 christos This file is part of the GNU C Library.
937 1.1 christos
938 1.1 christos The GNU C Library is free software; you can redistribute it and/or
939 1.1 christos modify it under the terms of the GNU Library General Public License as
940 1.1 christos published by the Free Software Foundation; either version 2 of the
941 1.1 christos License, or (at your option) any later version.
942 1.1 christos
943 1.1 christos The GNU C Library is distributed in the hope that it will be useful,
944 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
945 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
946 1.1 christos Library General Public License for more details.
947 1.1 christos
948 1.1 christos You should have received a copy of the GNU Library General Public
949 1.1 christos License along with the GNU C Library; see the file COPYING.LIB. If
950 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
951 1.1 christos Cambridge, MA 02139, USA. */
952 1.1 christos
953 1.1 christos #ifndef _MALLOC_INTERNAL
954 1.1 christos #define _MALLOC_INTERNAL
955 1.1 christos #include <malloc.h>
956 1.1 christos #endif
957 1.1 christos
958 1.1 christos #ifdef _LIBC
959 1.1 christos
960 1.1 christos #include <ansidecl.h>
961 1.1 christos #include <gnu-stabs.h>
962 1.1 christos
963 1.1 christos #undef cfree
964 1.1 christos
965 1.1 christos function_alias(cfree, free, void, (ptr),
966 1.1 christos DEFUN(cfree, (ptr), PTR ptr))
967 1.1 christos
968 1.1 christos #else
969 1.1 christos
970 1.1 christos void
971 1.1 christos cfree (ptr)
972 1.1 christos __ptr_t ptr;
973 1.1 christos {
974 1.1 christos free (ptr);
975 1.1 christos }
976 1.1 christos
977 1.1 christos #endif
978 1.1 christos /* Change the size of a block allocated by `malloc'.
979 1.1 christos Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
980 1.1 christos Written May 1989 by Mike Haertel.
981 1.1 christos
982 1.1 christos This library is free software; you can redistribute it and/or
983 1.1 christos modify it under the terms of the GNU Library General Public License as
984 1.1 christos published by the Free Software Foundation; either version 2 of the
985 1.1 christos License, or (at your option) any later version.
986 1.1 christos
987 1.1 christos This library is distributed in the hope that it will be useful,
988 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
989 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
990 1.1 christos Library General Public License for more details.
991 1.1 christos
992 1.1 christos You should have received a copy of the GNU Library General Public
993 1.1 christos License along with this library; see the file COPYING.LIB. If
994 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
995 1.1 christos Cambridge, MA 02139, USA.
996 1.1 christos
997 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu,
998 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */
999 1.1 christos
1000 1.1 christos #ifndef _MALLOC_INTERNAL
1001 1.1 christos #define _MALLOC_INTERNAL
1002 1.1 christos #include <malloc.h>
1003 1.1 christos #endif
1004 1.1 christos
1005 1.1 christos #if (defined (MEMMOVE_MISSING) || \
1006 1.1 christos !defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
1007 1.1 christos
1008 1.1 christos /* Snarfed directly from Emacs src/dispnew.c:
1009 1.1 christos XXX Should use system bcopy if it handles overlap. */
1010 1.1 christos #ifndef emacs
1011 1.1 christos
1012 1.1 christos /* Like bcopy except never gets confused by overlap. */
1013 1.1 christos
1014 1.1 christos static void
1015 1.1 christos safe_bcopy (from, to, size)
1016 1.1 christos char *from, *to;
1017 1.1 christos int size;
1018 1.1 christos {
1019 1.1 christos if (size <= 0 || from == to)
1020 1.1 christos return;
1021 1.1 christos
1022 1.1 christos /* If the source and destination don't overlap, then bcopy can
1023 1.1 christos handle it. If they do overlap, but the destination is lower in
1024 1.1 christos memory than the source, we'll assume bcopy can handle that. */
1025 1.1 christos if (to < from || from + size <= to)
1026 1.1 christos bcopy (from, to, size);
1027 1.1 christos
1028 1.1 christos /* Otherwise, we'll copy from the end. */
1029 1.1 christos else
1030 1.1 christos {
1031 1.1 christos register char *endf = from + size;
1032 1.1 christos register char *endt = to + size;
1033 1.1 christos
1034 1.1 christos /* If TO - FROM is large, then we should break the copy into
1035 1.1 christos nonoverlapping chunks of TO - FROM bytes each. However, if
1036 1.1 christos TO - FROM is small, then the bcopy function call overhead
1037 1.1 christos makes this not worth it. The crossover point could be about
1038 1.1 christos anywhere. Since I don't think the obvious copy loop is too
1039 1.1 christos bad, I'm trying to err in its favor. */
1040 1.1 christos if (to - from < 64)
1041 1.1 christos {
1042 1.1 christos do
1043 1.1 christos *--endt = *--endf;
1044 1.1 christos while (endf != from);
1045 1.1 christos }
1046 1.1 christos else
1047 1.1 christos {
1048 1.1 christos for (;;)
1049 1.1 christos {
1050 1.1 christos endt -= (to - from);
1051 1.1 christos endf -= (to - from);
1052 1.1 christos
1053 1.1 christos if (endt < to)
1054 1.1 christos break;
1055 1.1 christos
1056 1.1 christos bcopy (endf, endt, to - from);
1057 1.1 christos }
1058 1.1 christos
1059 1.1 christos /* If SIZE wasn't a multiple of TO - FROM, there will be a
1060 1.1 christos little left over. The amount left over is
1061 1.1 christos (endt + (to - from)) - to, which is endt - from. */
1062 1.1 christos bcopy (from, to, endt - from);
1063 1.1 christos }
1064 1.1 christos }
1065 1.1 christos }
1066 1.1 christos #endif /* Not emacs. */
1067 1.1 christos
1068 1.1 christos #define memmove(to, from, size) safe_bcopy ((from), (to), (size))
1069 1.1 christos
1070 1.1 christos #endif
1071 1.1 christos
1072 1.1 christos
1073 1.1 christos #define min(A, B) ((A) < (B) ? (A) : (B))
1074 1.1 christos
1075 1.1 christos /* Debugging hook for realloc. */
1076 1.1 christos __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size));
1077 1.1 christos
1078 1.1 christos /* Resize the given region to the new size, returning a pointer
1079 1.1 christos to the (possibly moved) region. This is optimized for speed;
1080 1.1 christos some benchmarks seem to indicate that greater compactness is
1081 1.1 christos achieved by unconditionally allocating and copying to a
1082 1.1 christos new region. This module has incestuous knowledge of the
1083 1.1 christos internals of both free and malloc. */
1084 1.1 christos __ptr_t
1085 1.1 christos realloc (ptr, size)
1086 1.1 christos __ptr_t ptr;
1087 1.1 christos __malloc_size_t size;
1088 1.1 christos {
1089 1.1 christos __ptr_t result;
1090 1.1 christos int type;
1091 1.1 christos __malloc_size_t block, blocks, oldlimit;
1092 1.1 christos
1093 1.1 christos if (size == 0)
1094 1.1 christos {
1095 1.1 christos free (ptr);
1096 1.1 christos return malloc (0);
1097 1.1 christos }
1098 1.1 christos else if (ptr == NULL)
1099 1.1 christos return malloc (size);
1100 1.1 christos
1101 1.1 christos if (__realloc_hook != NULL)
1102 1.1 christos return (*__realloc_hook) (ptr, size);
1103 1.1 christos
1104 1.1 christos block = BLOCK (ptr);
1105 1.1 christos
1106 1.1 christos type = _heapinfo[block].busy.type;
1107 1.1 christos switch (type)
1108 1.1 christos {
1109 1.1 christos case 0:
1110 1.1 christos /* Maybe reallocate a large block to a small fragment. */
1111 1.1 christos if (size <= BLOCKSIZE / 2)
1112 1.1 christos {
1113 1.1 christos result = malloc (size);
1114 1.1 christos if (result != NULL)
1115 1.1 christos {
1116 1.1 christos memcpy (result, ptr, size);
1117 1.1 christos _free_internal (ptr);
1118 1.1 christos return result;
1119 1.1 christos }
1120 1.1 christos }
1121 1.1 christos
1122 1.1 christos /* The new size is a large allocation as well;
1123 1.1 christos see if we can hold it in place. */
1124 1.1 christos blocks = BLOCKIFY (size);
1125 1.1 christos if (blocks < _heapinfo[block].busy.info.size)
1126 1.1 christos {
1127 1.1 christos /* The new size is smaller; return
1128 1.1 christos excess memory to the free list. */
1129 1.1 christos _heapinfo[block + blocks].busy.type = 0;
1130 1.1 christos _heapinfo[block + blocks].busy.info.size
1131 1.1 christos = _heapinfo[block].busy.info.size - blocks;
1132 1.1 christos _heapinfo[block].busy.info.size = blocks;
1133 1.1 christos /* We have just created a new chunk by splitting a chunk in two.
1134 1.1 christos Now we will free this chunk; increment the statistics counter
1135 1.1 christos so it doesn't become wrong when _free_internal decrements it. */
1136 1.1 christos ++_chunks_used;
1137 1.1 christos _free_internal (ADDRESS (block + blocks));
1138 1.1 christos result = ptr;
1139 1.1 christos }
1140 1.1 christos else if (blocks == _heapinfo[block].busy.info.size)
1141 1.1 christos /* No size change necessary. */
1142 1.1 christos result = ptr;
1143 1.1 christos else
1144 1.1 christos {
1145 1.1 christos /* Won't fit, so allocate a new region that will.
1146 1.1 christos Free the old region first in case there is sufficient
1147 1.1 christos adjacent free space to grow without moving. */
1148 1.1 christos blocks = _heapinfo[block].busy.info.size;
1149 1.1 christos /* Prevent free from actually returning memory to the system. */
1150 1.1 christos oldlimit = _heaplimit;
1151 1.1 christos _heaplimit = 0;
1152 1.1 christos _free_internal (ptr);
1153 1.1 christos _heaplimit = oldlimit;
1154 1.1 christos result = malloc (size);
1155 1.1 christos if (result == NULL)
1156 1.1 christos {
1157 1.1 christos /* Now we're really in trouble. We have to unfree
1158 1.1 christos the thing we just freed. Unfortunately it might
1159 1.1 christos have been coalesced with its neighbors. */
1160 1.1 christos if (_heapindex == block)
1161 1.1 christos (void) malloc (blocks * BLOCKSIZE);
1162 1.1 christos else
1163 1.1 christos {
1164 1.1 christos __ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE);
1165 1.1 christos (void) malloc (blocks * BLOCKSIZE);
1166 1.1 christos _free_internal (previous);
1167 1.1 christos }
1168 1.1 christos return NULL;
1169 1.1 christos }
1170 1.1 christos if (ptr != result)
1171 1.1 christos memmove (result, ptr, blocks * BLOCKSIZE);
1172 1.1 christos }
1173 1.1 christos break;
1174 1.1 christos
1175 1.1 christos default:
1176 1.1 christos /* Old size is a fragment; type is logarithm
1177 1.1 christos to base two of the fragment size. */
1178 1.1 christos if (size > (__malloc_size_t) (1 << (type - 1)) &&
1179 1.1 christos size <= (__malloc_size_t) (1 << type))
1180 1.1 christos /* The new size is the same kind of fragment. */
1181 1.1 christos result = ptr;
1182 1.1 christos else
1183 1.1 christos {
1184 1.1 christos /* The new size is different; allocate a new space,
1185 1.1 christos and copy the lesser of the new size and the old. */
1186 1.1 christos result = malloc (size);
1187 1.1 christos if (result == NULL)
1188 1.1 christos return NULL;
1189 1.1 christos memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type));
1190 1.1 christos free (ptr);
1191 1.1 christos }
1192 1.1 christos break;
1193 1.1 christos }
1194 1.1 christos
1195 1.1 christos return result;
1196 1.1 christos }
1197 1.1 christos /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
1198 1.1 christos
1199 1.1 christos This library is free software; you can redistribute it and/or
1200 1.1 christos modify it under the terms of the GNU Library General Public License as
1201 1.1 christos published by the Free Software Foundation; either version 2 of the
1202 1.1 christos License, or (at your option) any later version.
1203 1.1 christos
1204 1.1 christos This library is distributed in the hope that it will be useful,
1205 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
1206 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1207 1.1 christos Library General Public License for more details.
1208 1.1 christos
1209 1.1 christos You should have received a copy of the GNU Library General Public
1210 1.1 christos License along with this library; see the file COPYING.LIB. If
1211 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1212 1.1 christos Cambridge, MA 02139, USA.
1213 1.1 christos
1214 1.1 christos The author may be reached (Email) at the address mike (at) ai.mit.edu,
1215 1.1 christos or (US mail) as Mike Haertel c/o Free Software Foundation. */
1216 1.1 christos
1217 1.1 christos #ifndef _MALLOC_INTERNAL
1218 1.1 christos #define _MALLOC_INTERNAL
1219 1.1 christos #include <malloc.h>
1220 1.1 christos #endif
1221 1.1 christos
1222 1.1 christos /* Allocate an array of NMEMB elements each SIZE bytes long.
1223 1.1 christos The entire array is initialized to zeros. */
1224 1.1 christos __ptr_t
1225 1.1 christos calloc (nmemb, size)
1226 1.1 christos register __malloc_size_t nmemb;
1227 1.1 christos register __malloc_size_t size;
1228 1.1 christos {
1229 1.1 christos register __ptr_t result = malloc (nmemb * size);
1230 1.1 christos
1231 1.1 christos if (result != NULL)
1232 1.1 christos (void) memset (result, 0, nmemb * size);
1233 1.1 christos
1234 1.1 christos return result;
1235 1.1 christos }
1236 1.1 christos /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
1237 1.1 christos This file is part of the GNU C Library.
1238 1.1 christos
1239 1.1 christos The GNU C Library is free software; you can redistribute it and/or modify
1240 1.1 christos it under the terms of the GNU General Public License as published by
1241 1.1 christos the Free Software Foundation; either version 2, or (at your option)
1242 1.1 christos any later version.
1243 1.1 christos
1244 1.1 christos The GNU C Library is distributed in the hope that it will be useful,
1245 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
1246 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1247 1.1 christos GNU General Public License for more details.
1248 1.1 christos
1249 1.1 christos You should have received a copy of the GNU General Public License
1250 1.1 christos along with the GNU C Library; see the file COPYING. If not, write to
1251 1.1 christos the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
1252 1.1 christos
1253 1.1 christos #ifndef _MALLOC_INTERNAL
1254 1.1 christos #define _MALLOC_INTERNAL
1255 1.1 christos #include <malloc.h>
1256 1.1 christos #endif
1257 1.1 christos
1258 1.1 christos #ifndef __GNU_LIBRARY__
1259 1.1 christos #define __sbrk sbrk
1260 1.1 christos #endif
1261 1.1 christos
1262 1.1 christos #ifdef __GNU_LIBRARY__
1263 1.1 christos /* It is best not to declare this and cast its result on foreign operating
1264 1.1 christos systems with potentially hostile include files. */
1265 1.1 christos extern __ptr_t __sbrk __P ((int increment));
1266 1.1 christos #endif
1267 1.1 christos
1268 1.1 christos #ifndef NULL
1269 1.1 christos #define NULL 0
1270 1.1 christos #endif
1271 1.1 christos
1272 1.1 christos /* Allocate INCREMENT more bytes of data space,
1273 1.1 christos and return the start of data space, or NULL on errors.
1274 1.1 christos If INCREMENT is negative, shrink data space. */
1275 1.1 christos __ptr_t
1276 1.1 christos __default_morecore (increment)
1277 1.1 christos #ifdef __STDC__
1278 1.1 christos ptrdiff_t increment;
1279 1.1 christos #else
1280 1.1 christos int increment;
1281 1.1 christos #endif
1282 1.1 christos {
1283 1.1 christos __ptr_t result = (__ptr_t) __sbrk ((int) increment);
1284 1.1 christos if (result == (__ptr_t) -1)
1285 1.1 christos return NULL;
1286 1.1 christos return result;
1287 1.1 christos }
1288 1.1 christos /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
1289 1.1 christos
1290 1.1 christos This library is free software; you can redistribute it and/or
1291 1.1 christos modify it under the terms of the GNU Library General Public License as
1292 1.1 christos published by the Free Software Foundation; either version 2 of the
1293 1.1 christos License, or (at your option) any later version.
1294 1.1 christos
1295 1.1 christos This library is distributed in the hope that it will be useful,
1296 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
1297 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1298 1.1 christos Library General Public License for more details.
1299 1.1 christos
1300 1.1 christos You should have received a copy of the GNU Library General Public
1301 1.1 christos License along with this library; see the file COPYING.LIB. If
1302 1.1 christos not, write to the Free Software Foundation, Inc., 675 Mass Ave,
1303 1.1 christos Cambridge, MA 02139, USA. */
1304 1.1 christos
1305 1.1 christos #ifndef _MALLOC_INTERNAL
1306 1.1 christos #define _MALLOC_INTERNAL
1307 1.1 christos #include <malloc.h>
1308 1.1 christos #endif
1309 1.1 christos
1310 1.1 christos __ptr_t (*__memalign_hook) __P ((size_t __size, size_t __alignment));
1311 1.1 christos
1312 1.1 christos __ptr_t
1313 1.1 christos memalign (alignment, size)
1314 1.1 christos __malloc_size_t alignment;
1315 1.1 christos __malloc_size_t size;
1316 1.1 christos {
1317 1.1 christos __ptr_t result;
1318 1.1 christos unsigned long int adj;
1319 1.1 christos
1320 1.1 christos if (__memalign_hook)
1321 1.1 christos return (*__memalign_hook) (alignment, size);
1322 1.1 christos
1323 1.1 christos size = ((size + alignment - 1) / alignment) * alignment;
1324 1.1 christos
1325 1.1 christos result = malloc (size);
1326 1.1 christos if (result == NULL)
1327 1.1 christos return NULL;
1328 1.1 christos adj = (unsigned long int) ((unsigned long int) ((char *) result -
1329 1.1 christos (char *) NULL)) % alignment;
1330 1.1 christos if (adj != 0)
1331 1.1 christos {
1332 1.1 christos struct alignlist *l;
1333 1.1 christos for (l = _aligned_blocks; l != NULL; l = l->next)
1334 1.1 christos if (l->aligned == NULL)
1335 1.1 christos /* This slot is free. Use it. */
1336 1.1 christos break;
1337 1.1 christos if (l == NULL)
1338 1.1 christos {
1339 1.1 christos l = (struct alignlist *) malloc (sizeof (struct alignlist));
1340 1.1 christos if (l == NULL)
1341 1.1 christos {
1342 1.1 christos free (result);
1343 1.1 christos return NULL;
1344 1.1 christos }
1345 1.1 christos l->next = _aligned_blocks;
1346 1.1 christos _aligned_blocks = l;
1347 1.1 christos }
1348 1.1 christos l->exact = result;
1349 1.1 christos result = l->aligned = (char *) result + alignment - adj;
1350 1.1 christos }
1351 1.1 christos
1352 1.1 christos return result;
1353 }
1354