1 /* Synched up with: Not synched up with FSF 19.28, even though I
4 /* Get the configuration files if we're being compiled for Emacs. */
7 # include "getpagesize.h"
13 #if defined (__STDC__) && !defined (STDC_HEADERS)
14 /* The ANSI standard says that defining __STDC__ to a non-zero value means
15 that the compiler conforms to that standard. The standard requires
16 certain header files and library functions to be present. Therefore,
17 if your compiler defines __STDC__ to non-0 but does not have ANSI headers
18 and the ANSI library routines, then your compiler is buggy. Conversely,
19 an ANSI-conforming environment (which has both the ANSI headers and
20 library routines, i.e., stdlib.h and `memmove') does not necessarily
21 define the STDC_HEADERS flag. Lucid Emacs requires an ANSI compiler.
22 Therefore, there is no need to consult the abominable STDC_HEADERS flag.
29 /* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */
30 /* Bwaa-haa-haa! Not a chance that this is actually true! */
32 #define _MALLOC_INTERNAL
34 /* The malloc headers and source files from the C library follow here. */
36 /* Declarations for `malloc' and friends.
37 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
38 Written May 1989 by Mike Haertel.
40 This library is free software; you can redistribute it and/or
41 modify it under the terms of the GNU Library General Public License as
42 published by the Free Software Foundation; either version 2 of the
43 License, or (at your option) any later version.
45 This library is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48 Library General Public License for more details.
50 You should have received a copy of the GNU General Public License
51 along with this library; see the file COPYING. If not, write to
52 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
53 Boston, MA 02111-1307, USA.
55 The author may be reached (Email) at the address mike@ai.mit.edu,
56 or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */
62 #ifdef _MALLOC_INTERNAL
75 #endif /* _MALLOC_INTERNAL. */
84 #define __P(args) args
86 #define __ptr_t void *
89 #define __malloc_size_t size_t
95 /* XEmacs: I thought this should be int under SunOS, but that
96 apparently fails. Curses on all this shit. */
97 #define __free_ret_t void
99 /* XEmacs: I tried commenting these out and including stdlib.h,
100 but that fails badly. Urk! This sucks. */
101 /* Allocate SIZE bytes of memory. */
102 extern __ptr_t malloc __P ((size_t __size));
103 /* Re-allocate the previously allocated block
104 in __ptr_t, making the new block SIZE bytes long. */
105 extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size));
106 /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
107 extern __ptr_t calloc __P ((size_t __nmemb, size_t __size));
108 /* Free a block allocated by `malloc', `realloc' or `calloc'. */
109 extern __free_ret_t free __P ((__ptr_t __ptr));
111 /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
112 extern __ptr_t memalign __P ((size_t __alignment, size_t __size));
114 /* Allocate SIZE bytes on a page boundary. */
115 extern __ptr_t valloc __P ((size_t __size));
118 #ifdef _MALLOC_INTERNAL
120 /* The allocator divides the heap into blocks of fixed size; large
121 requests receive one or more whole blocks, and small requests
122 receive a fragment of a block. Fragment sizes are powers of two,
123 and all fragments of a block are the same size. When all the
124 fragments in a block have been freed, the block itself is freed. */
125 #define INT_BIT (CHAR_BIT * sizeof(int))
126 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
127 #define BLOCKSIZE (1 << BLOCKLOG)
128 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
130 /* Determine the amount of memory spanned by the initial heap table
131 (not an absolute limit). */
132 #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
134 /* Number of contiguous free blocks allowed to build up at the end of
135 memory before they will be returned to the system. */
136 #define FINAL_FREE_BLOCKS 8
138 /* Data structure giving per-block information. */
141 /* Heap information for a busy block. */
144 /* Zero for a large block, or positive giving the
145 logarithm to the base two of the fragment size. */
151 __malloc_size_t nfree; /* Free frags in a fragmented block. */
152 __malloc_size_t first; /* First free fragment of the block. */
154 /* Size (in blocks) of a large cluster. */
155 __malloc_size_t size;
158 /* Heap information for a free block
159 (that may be the first of a free cluster). */
162 __malloc_size_t size; /* Size (in blocks) of a free cluster. */
163 __malloc_size_t next; /* Index of next free cluster. */
164 __malloc_size_t prev; /* Index of previous free cluster. */
168 /* Pointer to first block of the heap. */
169 extern char *_heapbase;
171 /* Table indexed by block number giving per-block information. */
172 extern malloc_info *_heapinfo;
174 /* Address to block number and vice versa. */
175 #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
176 #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase))
178 /* Current search index for the heap table. */
179 extern __malloc_size_t _heapindex;
181 /* Limit of valid info table indices. */
182 extern __malloc_size_t _heaplimit;
184 /* Doubly linked lists of free fragments. */
191 /* Free list headers for each fragment size. */
192 extern struct list _fraghead[];
194 /* List of blocks allocated with `memalign' (or `valloc'). */
197 struct alignlist *next;
198 __ptr_t aligned; /* The address that memaligned returned. */
199 __ptr_t exact; /* The address that malloc returned. */
201 extern struct alignlist *_aligned_blocks;
203 /* Instrumentation. */
204 extern __malloc_size_t _chunks_used;
205 extern __malloc_size_t _bytes_used;
206 extern __malloc_size_t _chunks_free;
207 extern __malloc_size_t _bytes_free;
209 /* Internal version of `free' used in `morecore' (malloc.c). */
210 extern void _free_internal __P ((__ptr_t __ptr));
212 #endif /* _MALLOC_INTERNAL. */
214 /* Underlying allocation function; successive calls should
215 return contiguous pieces of memory. */
216 extern __ptr_t (*__morecore) __P ((ptrdiff_t __size));
218 /* Default value of `__morecore'. */
219 extern __ptr_t __default_morecore __P ((ptrdiff_t __size));
221 /* If not NULL, this function is called after each time
222 `__morecore' is called to increase the data size. */
223 extern void (*__after_morecore_hook) __P ((void));
225 /* Nonzero if `malloc' has been called and done its initialization. */
226 /* extern int __malloc_initialized; */
228 /* Hooks for debugging versions. */
229 extern void (*__free_hook) __P ((__ptr_t __ptr));
230 extern __ptr_t (*__malloc_hook) __P ((size_t __size));
231 extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size));
233 /* Return values for `mprobe': these are the kinds of inconsistencies that
234 `mcheck' enables detection of. */
237 MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
238 MCHECK_OK, /* Block is fine. */
239 MCHECK_FREE, /* Block freed twice. */
240 MCHECK_HEAD, /* Memory before the block was clobbered. */
241 MCHECK_TAIL /* Memory after the block was clobbered. */
244 /* Activate a standard collection of debugging hooks. This must be called
245 before `malloc' is ever called. ABORTFUNC is called with an error code
246 (see enum above) when an inconsistency is detected. If ABORTFUNC is
247 null, the standard function prints on stderr and then calls `abort'. */
248 extern int mcheck __P ((void (*__abortfunc) __P ((enum mcheck_status))));
250 /* Check for aberrations in a particular malloc'd block. You must have
251 called `mcheck' already. These are the same checks that `mcheck' does
252 when you free or reallocate a block. */
253 extern enum mcheck_status mprobe __P ((__ptr_t __ptr));
255 /* Activate a standard collection of tracing hooks. */
256 extern void mtrace __P ((void));
257 extern void muntrace __P ((void));
259 /* Statistics available to the user. */
262 __malloc_size_t bytes_total; /* Total size of the heap. */
263 __malloc_size_t chunks_used; /* Chunks allocated by the user. */
264 __malloc_size_t bytes_used; /* Byte total of user-allocated chunks. */
265 __malloc_size_t chunks_free; /* Chunks in the free list. */
266 __malloc_size_t bytes_free; /* Byte total of chunks in the free list. */
269 /* Pick up the current statistics. */
270 extern struct mstats mstats __P ((void));
272 /* Call WARNFUN with a warning message when memory usage is high. */
273 extern void memory_warnings __P ((__ptr_t __start,
274 void (*__warnfun) __P ((const char *))));
277 #if 0 /* unused in this file, and conflicting prototypes anyway */
278 /* Relocating allocator. */
280 /* Allocate SIZE bytes, and store the address in *HANDLEPTR. */
281 extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, size_t __size));
283 /* Free the storage allocated in HANDLEPTR. */
284 extern void r_alloc_free __P ((__ptr_t *__handleptr));
286 /* Adjust the block at HANDLEPTR to be SIZE bytes long. */
287 extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, size_t __size));
294 #endif /* malloc.h */
295 /* Allocate memory on a page boundary.
296 Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
298 This library is free software; you can redistribute it and/or
299 modify it under the terms of the GNU Library General Public License as
300 published by the Free Software Foundation; either version 2 of the
301 License, or (at your option) any later version.
303 This library is distributed in the hope that it will be useful,
304 but WITHOUT ANY WARRANTY; without even the implied warranty of
305 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
306 Library General Public License for more details.
308 You should have received a copy of the GNU General Public License
309 along with this library; see the file COPYING. If not, write to
310 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
311 Boston, MA 02111-1307, USA.
313 The author may be reached (Email) at the address mike@ai.mit.edu,
314 or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */
316 #if defined (__GNU_LIBRARY__) || defined (_LIBC)
318 #include <sys/cdefs.h>
319 #if ! (defined (__GLIBC__) && (__GLIBC__ >= 2))
320 extern size_t __getpagesize __P ((void));
323 #include "getpagesize.h"
324 #define __getpagesize() getpagesize()
327 #ifndef _MALLOC_INTERNAL
328 #define _MALLOC_INTERNAL
332 static __malloc_size_t pagesize;
335 valloc (__malloc_size_t size)
338 pagesize = __getpagesize ();
340 return memalign (pagesize, size);
342 /* Memory allocator `malloc'.
343 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation
344 Written May 1989 by Mike Haertel.
346 This library is free software; you can redistribute it and/or
347 modify it under the terms of the GNU Library General Public License as
348 published by the Free Software Foundation; either version 2 of the
349 License, or (at your option) any later version.
351 This library is distributed in the hope that it will be useful,
352 but WITHOUT ANY WARRANTY; without even the implied warranty of
353 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
354 Library General Public License for more details.
356 You should have received a copy of the GNU General Public License
357 along with this library; see the file COPYING. If not, write to
358 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
359 Boston, MA 02111-1307, USA.
361 The author may be reached (Email) at the address mike@ai.mit.edu,
362 or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */
364 #ifndef _MALLOC_INTERNAL
365 #define _MALLOC_INTERNAL
369 /* How to really get more memory. */
370 #if defined (HEAP_IN_DATA) && !defined(PDUMP)
371 /* once dumped, free() & realloc() on static heap space will fail */
372 #define PURE_DATA(x) \
373 ((static_heap_dumped && (char*)x >= static_heap_base \
374 && (char*)x <= (static_heap_base + static_heap_size) ) ? 1 : 0)
375 extern int initialized;
376 extern int purify_flag;
377 extern char* static_heap_base;
378 extern char* static_heap_ptr;
379 extern char* static_heap_dumped;
380 extern unsigned long static_heap_size;
381 extern __ptr_t more_static_core __P ((ptrdiff_t __size));
382 __ptr_t (*__morecore) __P ((ptrdiff_t __size)) = more_static_core;
384 __ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore;
385 #define PURE_DATA(x) 0
388 /* Debugging hook for `malloc'. */
389 __ptr_t (*__malloc_hook) __P ((__malloc_size_t __size));
391 /* Pointer to the base of the first block. */
394 /* Block information table. Allocated with align/__free (not malloc/free). */
395 malloc_info *_heapinfo;
397 /* Number of info entries. */
398 static __malloc_size_t heapsize;
400 /* Search index in the info table. */
401 __malloc_size_t _heapindex;
403 /* Limit of valid info table indices. */
404 __malloc_size_t _heaplimit;
406 /* Free lists for each fragment size. */
407 struct list _fraghead[BLOCKLOG];
409 /* Instrumentation. */
410 __malloc_size_t _chunks_used;
411 __malloc_size_t _bytes_used;
412 __malloc_size_t _chunks_free;
413 __malloc_size_t _bytes_free;
415 /* Are you experienced? */
416 int __malloc_initialized;
418 void (*__after_morecore_hook) __P ((void));
420 /* Aligned allocation. */
421 static __ptr_t align __P ((__malloc_size_t));
423 align (__malloc_size_t size)
426 unsigned long int adj;
428 result = (*__morecore) (size);
429 adj = (unsigned long int) ((unsigned long int) ((char *) result -
430 (char *) NULL)) % BLOCKSIZE;
433 adj = BLOCKSIZE - adj;
434 (void) (*__morecore) (adj);
435 result = (char *) result + adj;
438 if (__after_morecore_hook)
439 (*__after_morecore_hook) ();
444 /* Set everything up and remember that we have. */
445 static int initialize __P ((void));
449 #if defined (HEAP_IN_DATA) && !defined(PDUMP)
450 if (static_heap_dumped && __morecore == more_static_core)
452 __morecore = __default_morecore;
455 heapsize = HEAP / BLOCKSIZE;
456 _heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info));
457 if (_heapinfo == NULL)
459 memset (_heapinfo, 0, heapsize * sizeof (malloc_info));
460 memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
461 _heapinfo[0].free.size = 0;
462 _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
465 _heapbase = (char *) _heapinfo;
467 /* Account for the _heapinfo block itself in the statistics. */
468 _bytes_used = heapsize * sizeof (malloc_info);
474 __malloc_initialized = 1;
478 /* Get neatly aligned memory, initializing or
479 growing the heap info table as necessary. */
480 static __ptr_t morecore __P ((__malloc_size_t));
482 morecore (__malloc_size_t size)
485 malloc_info *newinfo, *oldinfo;
486 __malloc_size_t newsize;
488 result = align (size);
492 /* Check if we need to grow the info table. */
493 if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize)
496 while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize)
498 newinfo = (malloc_info *) align (newsize * sizeof (malloc_info));
501 (*__morecore) (-(int)size);
504 memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info));
505 memset (&newinfo[heapsize], 0,
506 (newsize - heapsize) * sizeof (malloc_info));
508 newinfo[BLOCK (oldinfo)].busy.type = 0;
509 newinfo[BLOCK (oldinfo)].busy.info.size
510 = BLOCKIFY (heapsize * sizeof (malloc_info));
512 /* Account for the _heapinfo block itself in the statistics. */
513 _bytes_used += newsize * sizeof (malloc_info);
515 _free_internal (oldinfo);
519 _heaplimit = BLOCK ((char *) result + size);
523 /* Allocate memory from the heap. */
525 malloc (__malloc_size_t size)
528 __malloc_size_t block, blocks, lastblocks, start;
532 /* ANSI C allows `malloc (0)' to either return NULL, or to return a
533 valid address you can realloc and free (though not dereference).
535 It turns out that some extant code (sunrpc, at least Ultrix's version)
536 expects `malloc (0)' to return non-NULL and breaks otherwise.
539 #ifdef HAVE_X_WINDOWS
540 /* there is at least one Xt bug where calloc(n,x) is blindly called
541 where n can be 0, and yet if 0 is returned, Xt barfs */
543 size = sizeof (struct list);
549 if (__malloc_hook != NULL)
550 return (*__malloc_hook) (size);
552 if (!__malloc_initialized)
556 #ifdef SUNOS_LOCALTIME_BUG
557 /* Workaround for localtime() allocating 8 bytes and writing 9 bug... */
562 if (size < sizeof (struct list))
563 size = sizeof (struct list);
565 /* Determine the allocation policy based on the request size. */
566 if (size <= BLOCKSIZE / 2)
568 /* Small allocation to receive a fragment of a block.
569 Determine the logarithm to base two of the fragment size. */
570 __malloc_size_t log = 1;
572 while ((size /= 2) != 0)
575 /* Look in the fragment lists for a
576 free fragment of the desired size. */
577 next = _fraghead[log].next;
580 /* There are free fragments of this size.
581 Pop a fragment out of the fragment list and return it.
582 Update the block's nfree and first counters. */
583 result = (__ptr_t) next;
584 next->prev->next = next->next;
585 if (next->next != NULL)
586 next->next->prev = next->prev;
587 block = BLOCK (result);
588 if (--_heapinfo[block].busy.info.frag.nfree != 0)
589 _heapinfo[block].busy.info.frag.first = (unsigned long int)
590 ((unsigned long int) ((char *) next->next - (char *) NULL)
593 /* Update the statistics. */
595 _bytes_used += 1 << log;
597 _bytes_free -= 1 << log;
601 /* No free fragments of the desired size, so get a new block
602 and break it into fragments, returning the first. */
603 result = malloc (BLOCKSIZE);
607 /* Link all fragments but the first into the free list. */
608 for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i)
610 next = (struct list *) ((char *) result + (i << log));
611 next->next = _fraghead[log].next;
612 next->prev = &_fraghead[log];
613 next->prev->next = next;
614 if (next->next != NULL)
615 next->next->prev = next;
618 /* Initialize the nfree and first counters for this block. */
619 block = BLOCK (result);
620 _heapinfo[block].busy.type = log;
621 _heapinfo[block].busy.info.frag.nfree = i - 1;
622 _heapinfo[block].busy.info.frag.first = i - 1;
624 _chunks_free += (BLOCKSIZE >> log) - 1;
625 _bytes_free += BLOCKSIZE - (1 << log);
626 _bytes_used -= BLOCKSIZE - (1 << log);
631 /* Large allocation to receive one or more blocks.
632 Search the free list in a circle starting at the last place visited.
633 If we loop completely around without finding a large enough
634 space we will have to get more memory from the system. */
635 blocks = BLOCKIFY (size);
636 start = block = _heapindex;
637 while (_heapinfo[block].free.size < blocks)
639 block = _heapinfo[block].free.next;
642 /* Need to get more from the system. Check to see if
643 the new core will be contiguous with the final free
644 block; if so we don't need to get as much. */
645 block = _heapinfo[0].free.prev;
646 lastblocks = _heapinfo[block].free.size;
647 if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
648 (*__morecore) (0) == ADDRESS (block + lastblocks) &&
649 (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL)
651 /* Which block we are extending (the `final free
652 block' referred to above) might have changed, if
653 it got combined with a freed info table. */
654 block = _heapinfo[0].free.prev;
655 _heapinfo[block].free.size += (blocks - lastblocks);
656 _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
659 result = morecore (blocks * BLOCKSIZE);
662 block = BLOCK (result);
663 _heapinfo[block].busy.type = 0;
664 _heapinfo[block].busy.info.size = blocks;
666 _bytes_used += blocks * BLOCKSIZE;
671 /* At this point we have found a suitable free list entry.
672 Figure out how to remove what we need from the list. */
673 result = ADDRESS (block);
674 if (_heapinfo[block].free.size > blocks)
676 /* The block we found has a bit left over,
677 so relink the tail end back into the free list. */
678 _heapinfo[block + blocks].free.size
679 = _heapinfo[block].free.size - blocks;
680 _heapinfo[block + blocks].free.next
681 = _heapinfo[block].free.next;
682 _heapinfo[block + blocks].free.prev
683 = _heapinfo[block].free.prev;
684 _heapinfo[_heapinfo[block].free.prev].free.next
685 = _heapinfo[_heapinfo[block].free.next].free.prev
686 = _heapindex = block + blocks;
690 /* The block exactly matches our requirements,
691 so just remove it from the list. */
692 _heapinfo[_heapinfo[block].free.next].free.prev
693 = _heapinfo[block].free.prev;
694 _heapinfo[_heapinfo[block].free.prev].free.next
695 = _heapindex = _heapinfo[block].free.next;
699 _heapinfo[block].busy.type = 0;
700 _heapinfo[block].busy.info.size = blocks;
702 _bytes_used += blocks * BLOCKSIZE;
703 _bytes_free -= blocks * BLOCKSIZE;
711 /* On some ANSI C systems, some libc functions call _malloc, _free
712 and _realloc. Make them use the GNU functions. */
714 __ptr_t _malloc (__malloc_size_t size);
716 _malloc (__malloc_size_t size)
718 return malloc (size);
721 void _free (__ptr_t ptr);
728 __ptr_t _realloc (__ptr_t ptr, __malloc_size_t size);
730 _realloc (__ptr_t ptr, __malloc_size_t size)
732 return realloc (ptr, size);
736 /* Free a block of memory allocated by `malloc'.
737 Copyright 1990, 1991, 1992, 1994 Free Software Foundation
738 Written May 1989 by Mike Haertel.
740 This library is free software; you can redistribute it and/or
741 modify it under the terms of the GNU Library General Public License as
742 published by the Free Software Foundation; either version 2 of the
743 License, or (at your option) any later version.
745 This library is distributed in the hope that it will be useful,
746 but WITHOUT ANY WARRANTY; without even the implied warranty of
747 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
748 Library General Public License for more details.
750 You should have received a copy of the GNU General Public License
751 along with this library; see the file COPYING. If not, write to
752 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
753 Boston, MA 02111-1307, USA.
755 The author may be reached (Email) at the address mike@ai.mit.edu,
756 or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */
758 #ifndef _MALLOC_INTERNAL
759 #define _MALLOC_INTERNAL
763 /* Debugging hook for free. */
764 void (*__free_hook) __P ((__ptr_t __ptr));
766 /* List of blocks allocated by memalign. */
767 struct alignlist *_aligned_blocks = NULL;
769 /* Return memory to the heap.
770 Like `free' but don't call a __free_hook if there is one. */
772 _free_internal (__ptr_t ptr)
775 __malloc_size_t block, blocks;
777 struct list *prev, *next;
781 type = _heapinfo[block].busy.type;
785 /* Get as many statistics as early as we can. */
787 _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
788 _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
790 /* Find the free cluster previous to this one in the free list.
791 Start searching at the last block referenced; this may benefit
792 programs with locality of allocation. */
796 i = _heapinfo[i].free.prev;
800 i = _heapinfo[i].free.next;
801 while (i > 0 && i < block);
802 i = _heapinfo[i].free.prev;
805 /* Determine how to link this block into the free list. */
806 if (block == i + _heapinfo[i].free.size)
808 /* Coalesce this block with its predecessor. */
809 _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
814 /* Really link this block back into the free list. */
815 _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
816 _heapinfo[block].free.next = _heapinfo[i].free.next;
817 _heapinfo[block].free.prev = i;
818 _heapinfo[i].free.next = block;
819 _heapinfo[_heapinfo[block].free.next].free.prev = block;
823 /* Now that the block is linked in, see if we can coalesce it
824 with its successor (by deleting its successor from the list
825 and adding in its size). */
826 if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
828 _heapinfo[block].free.size
829 += _heapinfo[_heapinfo[block].free.next].free.size;
830 _heapinfo[block].free.next
831 = _heapinfo[_heapinfo[block].free.next].free.next;
832 _heapinfo[_heapinfo[block].free.next].free.prev = block;
836 /* Now see if we can return stuff to the system. */
837 blocks = _heapinfo[block].free.size;
838 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
839 && (*__morecore) (0) == ADDRESS (block + blocks))
841 __malloc_size_t bytes = blocks * BLOCKSIZE;
842 _heaplimit -= blocks;
843 (*__morecore) (-(int)bytes);
844 _heapinfo[_heapinfo[block].free.prev].free.next
845 = _heapinfo[block].free.next;
846 _heapinfo[_heapinfo[block].free.next].free.prev
847 = _heapinfo[block].free.prev;
848 block = _heapinfo[block].free.prev;
850 _bytes_free -= bytes;
853 /* Set the next search to begin at this block. */
858 /* Do some of the statistics. */
860 _bytes_used -= 1 << type;
862 _bytes_free += 1 << type;
864 /* Get the address of the first free fragment in this block. */
865 prev = (struct list *) ((char *) ADDRESS (block) +
866 (_heapinfo[block].busy.info.frag.first << type));
868 if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
870 /* If all fragments of this block are free, remove them
871 from the fragment list and free the whole block. */
873 for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i)
875 prev->prev->next = next;
877 next->prev = prev->prev;
878 _heapinfo[block].busy.type = 0;
879 _heapinfo[block].busy.info.size = 1;
881 /* Keep the statistics accurate. */
883 _bytes_used += BLOCKSIZE;
884 _chunks_free -= BLOCKSIZE >> type;
885 _bytes_free -= BLOCKSIZE;
887 free (ADDRESS (block));
889 else if (_heapinfo[block].busy.info.frag.nfree != 0)
891 /* If some fragments of this block are free, link this
892 fragment into the fragment list after the first free
893 fragment of this block. */
894 next = (struct list *) ptr;
895 next->next = prev->next;
898 if (next->next != NULL)
899 next->next->prev = next;
900 ++_heapinfo[block].busy.info.frag.nfree;
904 /* No fragments of this block are free, so link this
905 fragment into the fragment list and announce that
906 it is the first free fragment of this block. */
907 prev = (struct list *) ptr;
908 _heapinfo[block].busy.info.frag.nfree = 1;
909 _heapinfo[block].busy.info.frag.first = (unsigned long int)
910 ((unsigned long int) ((char *) ptr - (char *) NULL)
911 % BLOCKSIZE >> type);
912 prev->next = _fraghead[type].next;
913 prev->prev = &_fraghead[type];
914 prev->prev->next = prev;
915 if (prev->next != NULL)
916 prev->next->prev = prev;
922 /* Return memory to the heap. */
936 for (l = _aligned_blocks; l != NULL; l = l->next)
937 if (l->aligned == ptr)
939 l->aligned = NULL; /* Mark the slot in the list as free. */
944 if (__free_hook != NULL)
945 (*__free_hook) (ptr);
947 _free_internal (ptr);
949 /* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
950 This file is part of the GNU C Library.
952 The GNU C Library is free software; you can redistribute it and/or
953 modify it under the terms of the GNU Library General Public License as
954 published by the Free Software Foundation; either version 2 of the
955 License, or (at your option) any later version.
957 The GNU C Library is distributed in the hope that it will be useful,
958 but WITHOUT ANY WARRANTY; without even the implied warranty of
959 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
960 Library General Public License for more details.
962 You should have received a copy of the GNU General Public License
963 along with this library; see the file COPYING. If not, write to
964 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
965 Boston, MA 02111-1307, USA. */
967 #ifndef _MALLOC_INTERNAL
968 #define _MALLOC_INTERNAL
974 #include <ansidecl.h>
975 #include <gnu-stabs.h>
979 function_alias(cfree, free, void, (ptr),
980 DEFUN(cfree, (ptr), PTR ptr))
984 void cfree (__ptr_t ptr);
992 /* Change the size of a block allocated by `malloc'.
993 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
994 Written May 1989 by Mike Haertel.
996 This library is free software; you can redistribute it and/or
997 modify it under the terms of the GNU Library General Public License as
998 published by the Free Software Foundation; either version 2 of the
999 License, or (at your option) any later version.
1001 This library is distributed in the hope that it will be useful,
1002 but WITHOUT ANY WARRANTY; without even the implied warranty of
1003 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1004 Library General Public License for more details.
1006 You should have received a copy of the GNU General Public License
1007 along with this library; see the file COPYING. If not, write to
1008 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1009 Boston, MA 02111-1307, USA.
1011 The author may be reached (Email) at the address mike@ai.mit.edu,
1012 or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */
1014 #ifndef _MALLOC_INTERNAL
1015 #define _MALLOC_INTERNAL
1020 #define min(A, B) ((A) < (B) ? (A) : (B))
1023 /* Debugging hook for realloc. */
1024 __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size));
1026 /* Resize the given region to the new size, returning a pointer
1027 to the (possibly moved) region. This is optimized for speed;
1028 some benchmarks seem to indicate that greater compactness is
1029 achieved by unconditionally allocating and copying to a
1030 new region. This module has incestuous knowledge of the
1031 internals of both free and malloc. */
1033 realloc (__ptr_t ptr, __malloc_size_t size)
1037 __malloc_size_t block, blocks, oldlimit;
1039 if (PURE_DATA (ptr))
1041 result = malloc (size);
1042 memcpy(result, ptr, size);
1051 else if (ptr == NULL)
1052 return malloc (size);
1054 if (__realloc_hook != NULL)
1055 return (*__realloc_hook) (ptr, size);
1057 block = BLOCK (ptr);
1059 type = _heapinfo[block].busy.type;
1063 /* Maybe reallocate a large block to a small fragment. */
1064 if (size <= BLOCKSIZE / 2)
1066 result = malloc (size);
1069 memcpy (result, ptr, size);
1070 _free_internal (ptr);
1075 /* The new size is a large allocation as well;
1076 see if we can hold it in place. */
1077 blocks = BLOCKIFY (size);
1078 if (blocks < _heapinfo[block].busy.info.size)
1080 /* The new size is smaller; return
1081 excess memory to the free list. */
1082 _heapinfo[block + blocks].busy.type = 0;
1083 _heapinfo[block + blocks].busy.info.size
1084 = _heapinfo[block].busy.info.size - blocks;
1085 _heapinfo[block].busy.info.size = blocks;
1086 /* We have just created a new chunk by splitting a chunk in two.
1087 Now we will free this chunk; increment the statistics counter
1088 so it doesn't become wrong when _free_internal decrements it. */
1090 _free_internal (ADDRESS (block + blocks));
1093 else if (blocks == _heapinfo[block].busy.info.size)
1094 /* No size change necessary. */
1098 /* Won't fit, so allocate a new region that will.
1099 Free the old region first in case there is sufficient
1100 adjacent free space to grow without moving. */
1101 blocks = _heapinfo[block].busy.info.size;
1102 /* Prevent free from actually returning memory to the system. */
1103 oldlimit = _heaplimit;
1106 _heaplimit = oldlimit;
1107 result = malloc (size);
1110 /* Now we're really in trouble. We have to unfree
1111 the thing we just freed. Unfortunately it might
1112 have been coalesced with its neighbors. */
1113 if (_heapindex == block)
1114 (void) malloc (blocks * BLOCKSIZE);
1117 __ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE);
1118 (void) malloc (blocks * BLOCKSIZE);
1124 memmove (result, ptr, blocks * BLOCKSIZE);
1129 /* Old size is a fragment; type is logarithm
1130 to base two of the fragment size. */
1131 if (size > (__malloc_size_t) (1 << (type - 1)) &&
1132 size <= (__malloc_size_t) (1 << type))
1133 /* The new size is the same kind of fragment. */
1137 /* The new size is different; allocate a new space,
1138 and copy the lesser of the new size and the old. */
1139 result = malloc (size);
1142 memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type));
1150 /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
1152 This library is free software; you can redistribute it and/or
1153 modify it under the terms of the GNU Library General Public License as
1154 published by the Free Software Foundation; either version 2 of the
1155 License, or (at your option) any later version.
1157 This library is distributed in the hope that it will be useful,
1158 but WITHOUT ANY WARRANTY; without even the implied warranty of
1159 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1160 Library General Public License for more details.
1162 You should have received a copy of the GNU General Public License
1163 along with this library; see the file COPYING. If not, write to
1164 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1165 Boston, MA 02111-1307, USA.
1167 The author may be reached (Email) at the address mike@ai.mit.edu,
1168 or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */
1170 #ifndef _MALLOC_INTERNAL
1171 #define _MALLOC_INTERNAL
1175 /* Allocate an array of NMEMB elements each SIZE bytes long.
1176 The entire array is initialized to zeros. */
1178 calloc (__malloc_size_t nmemb, __malloc_size_t size)
1180 __ptr_t result = malloc (nmemb * size);
1183 (void) memset (result, 0, nmemb * size);
1187 /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
1188 This file is part of the GNU C Library.
1190 The GNU C Library is free software; you can redistribute it and/or modify
1191 it under the terms of the GNU General Public License as published by
1192 the Free Software Foundation; either version 2, or (at your option)
1195 The GNU C Library is distributed in the hope that it will be useful,
1196 but WITHOUT ANY WARRANTY; without even the implied warranty of
1197 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1198 GNU General Public License for more details.
1200 You should have received a copy of the GNU General Public License
1201 along with the GNU C Library; see the file COPYING. If not, write to
1202 the Free the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1203 Boston, MA 02111-1307, USA. */
1205 #ifndef _MALLOC_INTERNAL
1206 #define _MALLOC_INTERNAL
1210 /* #ifndef __GNU_LIBRARY__ */
1214 #ifdef GMALLOC_NEEDS_SBRK_DECL
1215 /* some versions of OSF1 need this */
1216 extern __ptr_t __sbrk __P ((ssize_t increment));
1218 #ifdef __GNU_LIBRARY__
1219 /* It is best not to declare this and cast its result on foreign operating
1220 systems with potentially hostile include files. */
1221 #if !(defined(linux) && defined(sparc))
1222 extern __ptr_t __sbrk __P ((int increment));
1231 /* Allocate INCREMENT more bytes of data space,
1232 and return the start of data space, or NULL on errors.
1233 If INCREMENT is negative, shrink data space. */
1235 __default_morecore (ptrdiff_t increment)
1237 __ptr_t result = (__ptr_t) __sbrk (increment);
1238 if (result == (__ptr_t) -1)
1242 /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
1244 This library is free software; you can redistribute it and/or
1245 modify it under the terms of the GNU Library General Public License as
1246 published by the Free Software Foundation; either version 2 of the
1247 License, or (at your option) any later version.
1249 This library is distributed in the hope that it will be useful,
1250 but WITHOUT ANY WARRANTY; without even the implied warranty of
1251 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1252 Library General Public License for more details.
1254 You should have received a copy of the GNU General Public License
1255 along with this library; see the file COPYING. If not, write to
1256 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1257 Boston, MA 02111-1307, USA. */
1259 #ifndef _MALLOC_INTERNAL
1260 #define _MALLOC_INTERNAL
1265 memalign (__malloc_size_t alignment, __malloc_size_t size)
1268 unsigned long int adj;
1270 size = ((size + alignment - 1) / alignment) * alignment;
1272 result = malloc (size);
1275 adj = (unsigned long int) ((unsigned long int) ((char *) result -
1276 (char *) NULL)) % alignment;
1279 struct alignlist *l;
1280 for (l = _aligned_blocks; l != NULL; l = l->next)
1281 if (l->aligned == NULL)
1282 /* This slot is free. Use it. */
1286 l = (struct alignlist *) malloc (sizeof (struct alignlist));
1292 l->next = _aligned_blocks;
1293 _aligned_blocks = l;
1296 result = l->aligned = (char *) result + alignment - adj;