2 /* gmalloc.c - THIS FILE IS AUTOMAGICALLY GENERATED SO DON'T EDIT IT. */
4 /* Single-file skeleton for GNU malloc.
5 Copyright 1989 Free Software Foundation
6 Written May 1989 by Mike Haertel.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 or (US mail) as Mike Haertel c/o Free Software Foundation. */
27 /* DO NOT DELETE THIS LINE -- ansidecl.h INSERTED HERE. */
28 /* Copyright (C) 1989 Free Software Foundation, Inc.
29 This file is part of the GNU C Library.
31 The GNU C Library is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version 1, or (at your option)
36 The GNU C Library is distributed in the hope that it will be useful,
37 but WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 GNU General Public License for more details.
41 You should have received a copy of the GNU General Public License
42 along with the GNU C Library; see the file COPYING. If not, write to
43 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
45 /* ANSI and traditional C compatibility macros
47 ANSI C is assumed if __STDC__ is #defined.
50 PTR - Generic pointer type
51 LONG_DOUBLE - `long double' type
52 CONST - `const' keyword
53 VOLATILE - `volatile' keyword
54 SIGNED - `signed' keyword
55 PTRCONST - Generic const pointer (void *const)
57 EXFUN(name, prototype) - declare external function NAME
58 with prototype PROTOTYPE
59 DEFUN(name, arglist, args) - define function NAME with
60 args ARGLIST of types in ARGS
61 DEFUN_VOID(name) - define function NAME with no args
62 AND - argument separator for ARGS
67 extern int EXFUN(printf, (CONST char *format DOTS));
68 int DEFUN(fprintf, (stream, format),
69 FILE *stream AND CONST char *format DOTS) { ... }
70 void DEFUN_VOID(abort) { ... }
78 /* Every source file includes this file,
79 so they will all get the switch for lint. */
86 #define PTRCONST void *CONST
87 #define LONG_DOUBLE long double
92 #define VOLATILE volatile
96 #define EXFUN(name, proto) name proto
97 #define DEFUN(name, arglist, args) name(args)
98 #define DEFUN_VOID(name) name(NOARGS)
100 #else /* Not ANSI C. */
104 #define LONG_DOUBLE double
113 #define EXFUN(name, proto) name()
114 #define DEFUN(name, arglist, args) name arglist args;
115 #define DEFUN_VOID(name) name()
120 #endif /* ansidecl.h */
125 /* DO NOT DELETE THIS LINE -- limits.h INSERTED HERE. */
126 /* Number of bits in a `char'. */
129 /* No multibyte characters supported yet. */
132 /* Minimum and maximum values a `signed char' can hold. */
133 #define SCHAR_MIN -128
134 #define SCHAR_MAX 127
136 /* Maximum value an `unsigned char' can hold. (Minimum is 0). */
137 #define UCHAR_MAX 255U
139 /* Minimum and maximum values a `char' can hold. */
140 #ifdef __CHAR_UNSIGNED__
142 #define CHAR_MAX 255U
144 #define CHAR_MIN -128
148 /* Minimum and maximum values a `signed short int' can hold. */
149 #define SHRT_MIN -32768
150 #define SHRT_MAX 32767
152 /* Maximum value an `unsigned short int' can hold. (Minimum is 0). */
153 #define USHRT_MAX 65535U
155 /* Minimum and maximum values a `signed int' can hold. */
156 #define INT_MIN -2147483648
157 #define INT_MAX 2147483647
159 /* Maximum value an `unsigned int' can hold. (Minimum is 0). */
160 #define UINT_MAX 4294967295U
162 /* Minimum and maximum values a `signed long int' can hold.
164 #define LONG_MIN (-LONG_MAX-1)
165 #define LONG_MAX 2147483647
167 /* Maximum value an `unsigned long int' can hold. (Minimum is 0). */
168 #define ULONG_MAX 4294967295U
174 /* DO NOT DELETE THIS LINE -- stddef.h INSERTED HERE. */
178 /* Signed type of difference of two pointers. */
180 typedef long ptrdiff_t;
182 /* Unsigned type of `sizeof' something. */
184 #ifndef _SIZE_T /* in case <sys/types.h> has defined it. */
186 typedef unsigned long size_t;
189 /* A null pointer constant. */
191 #undef NULL /* in case <stdio.h> has defined it. */
194 /* Offset of member MEMBER in a struct of type TYPE. */
196 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
198 #endif /* _STDDEF_H */
201 /* DO NOT DELETE THIS LINE -- stdlib.h INSERTED HERE. */
202 /* Fake stdlib.h supplying the stuff needed by malloc. */
208 extern void EXFUN(abort, (void));
209 extern void EXFUN(free, (PTR));
210 extern PTR EXFUN(malloc, (size_t));
211 extern PTR EXFUN(realloc, (PTR, size_t));
213 /* DO NOT DELETE THIS LINE -- string.h INSERTED HERE. */
214 /* Fake string.h supplying stuff used by malloc. */
219 extern PTR EXFUN(memcpy, (PTR, PTR, size_t));
220 extern PTR EXFUN(memset, (PTR, int, size_t));
221 #define memmove memcpy
223 #define _MALLOC_INTERNAL
224 /* DO NOT DELETE THIS LINE -- malloc.h INSERTED HERE. */
225 /* Declarations for `malloc' and friends.
226 Copyright 1990 Free Software Foundation
227 Written May 1989 by Mike Haertel.
229 This program is free software; you can redistribute it and/or modify
230 it under the terms of the GNU General Public License as published by
231 the Free Software Foundation; either version 1, or (at your option)
234 This program is distributed in the hope that it will be useful,
235 but WITHOUT ANY WARRANTY; without even the implied warranty of
236 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
237 GNU General Public License for more details.
239 You should have received a copy of the GNU General Public License
240 along with this program; if not, write to the Free Software
241 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
243 The author may be reached (Email) at the address mike@@ai.mit.edu,
244 or (US mail) as Mike Haertel c/o Free Software Foundation. */
252 #define __need_size_t
253 #define __need_ptrdiff_t
257 #ifdef _MALLOC_INTERNAL
263 /* The allocator divides the heap into blocks of fixed size; large
264 requests receive one or more whole blocks, and small requests
265 receive a fragment of a block. Fragment sizes are powers of two,
266 and all fragments of a block are the same size. When all the
267 fragments in a block have been freed, the block itself is freed. */
268 #define INT_BIT (CHAR_BIT * sizeof(int))
269 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
270 #define BLOCKSIZE (1 << BLOCKLOG)
271 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
273 /* Determine the amount of memory spanned by the initial heap table
274 (not an absolute limit). */
275 #define HEAP (INT_BIT > 16 ? 4194304 : 65536)
277 /* Number of contiguous free blocks allowed to build up at the end of
278 memory before they will be returned to the system. */
279 #define FINAL_FREE_BLOCKS 8
281 /* Where to start searching the free list when looking for new memory.
282 The two possible values are 0 and _heapindex. Starting at 0 seems
283 to reduce total memory usage, while starting at _heapindex seems to
285 #define MALLOC_SEARCH_START _heapindex
287 /* Data structure giving per-block information. */
290 /* Heap information for a busy block. */
293 /* Zero for a large block, or positive giving the
294 logarithm to the base two of the fragment size. */
300 size_t nfree; /* Free fragments in a fragmented block. */
301 size_t first; /* First free fragment of the block. */
303 /* Size (in blocks) of a large cluster. */
307 /* Heap information for a free block (that may be the first of
311 size_t size; /* Size (in blocks) of a free cluster. */
312 size_t next; /* Index of next free cluster. */
313 size_t prev; /* Index of previous free cluster. */
317 /* Pointer to first block of the heap. */
318 extern char *_heapbase;
320 /* Table indexed by block number giving per-block information. */
321 extern malloc_info *_heapinfo;
323 /* Address to block number and vice versa. */
324 #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
325 #define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + _heapbase))
327 /* Current search index for the heap table. */
328 extern size_t _heapindex;
330 /* Limit of valid info table indices. */
331 extern size_t _heaplimit;
333 /* Doubly linked lists of free fragments. */
340 /* Free list headers for each fragment size. */
341 extern struct list _fraghead[];
343 /* Instrumentation. */
344 extern size_t _chunks_used;
345 extern size_t _bytes_used;
346 extern size_t _chunks_free;
347 extern size_t _bytes_free;
349 /* Internal version of free() used in morecore(). */
350 extern void EXFUN(__free, (PTR __ptr));
352 #endif /* _MALLOC_INTERNAL. */
354 /* Underlying allocation function; successive calls should
355 return contiguous pieces of memory. */
356 extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
358 /* Default value of previous. */
359 extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
361 /* Flag whether malloc has been called. */
362 extern int __malloc_initialized;
364 /* Hooks for debugging versions. */
365 extern void EXFUN((*__free_hook), (PTR __ptr));
366 extern PTR EXFUN((*__malloc_hook), (size_t __size));
367 extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
369 /* Activate a standard collection of debugging hooks. */
370 extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
372 /* Statistics available to the user. */
375 size_t bytes_total; /* Total size of the heap. */
376 size_t chunks_used; /* Chunks allocated by the user. */
377 size_t bytes_used; /* Byte total of user-allocated chunks. */
378 size_t chunks_free; /* Chunks in the free list. */
379 size_t bytes_free; /* Byte total of chunks in the free list. */
382 /* Pick up the current statistics. */
383 extern struct mstats EXFUN(mstats, (NOARGS));
385 #endif /* malloc.h */
387 /* DO NOT DELETE THIS LINE -- free.c INSERTED HERE. */
388 /* Free a block of memory allocated by `malloc'.
389 Copyright 1990 Free Software Foundation
390 Written May 1989 by Mike Haertel.
392 This program is free software; you can redistribute it and/or modify
393 it under the terms of the GNU General Public License as published by
394 the Free Software Foundation; either version 1, or (at your option)
397 This program is distributed in the hope that it will be useful,
398 but WITHOUT ANY WARRANTY; without even the implied warranty of
399 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
400 GNU General Public License for more details.
402 You should have received a copy of the GNU General Public License
403 along with this program; if not, write to the Free Software
404 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
407 or (US mail) as Mike Haertel c/o Free Software Foundation. */
410 #include "ansidecl.h"
414 #define _MALLOC_INTERNAL
416 #endif /* __ONEFILE */
418 /* Debugging hook for free. */
419 void EXFUN((*__free_hook), (PTR __ptr));
421 /* Return memory to the heap. Like free() but don't call a __free_hook
424 DEFUN(__free, (ptr), PTR ptr)
427 size_t block, blocks;
429 struct list *prev, *next;
433 type = _heapinfo[block].busy.type;
437 /* Get as many statistics as early as we can. */
439 _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
440 _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
442 /* Find the free cluster previous to this one in the free list.
443 Start searching at the last block referenced; this may benefit
444 programs with locality of allocation. */
448 i = _heapinfo[i].free.prev;
452 i = _heapinfo[i].free.next;
453 while (i > 0 && i < block);
454 i = _heapinfo[i].free.prev;
457 /* Determine how to link this block into the free list. */
458 if (block == i + _heapinfo[i].free.size)
460 /* Coalesce this block with its predecessor. */
461 _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
466 /* Really link this block back into the free list. */
467 _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
468 _heapinfo[block].free.next = _heapinfo[i].free.next;
469 _heapinfo[block].free.prev = i;
470 _heapinfo[i].free.next = block;
471 _heapinfo[_heapinfo[block].free.next].free.prev = block;
475 /* Now that the block is linked in, see if we can coalesce it
476 with its successor (by deleting its successor from the list
477 and adding in its size). */
478 if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
480 _heapinfo[block].free.size
481 += _heapinfo[_heapinfo[block].free.next].free.size;
482 _heapinfo[block].free.next
483 = _heapinfo[_heapinfo[block].free.next].free.next;
484 _heapinfo[_heapinfo[block].free.next].free.prev = block;
488 /* Now see if we can return stuff to the system. */
489 blocks = _heapinfo[block].free.size;
490 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
491 && (*__morecore)(0) == ADDRESS(block + blocks))
493 register size_t bytes = blocks * BLOCKSIZE;
494 _heaplimit -= blocks;
495 (*__morecore)(- bytes);
496 _heapinfo[_heapinfo[block].free.prev].free.next
497 = _heapinfo[block].free.next;
498 _heapinfo[_heapinfo[block].free.next].free.prev
499 = _heapinfo[block].free.prev;
500 block = _heapinfo[block].free.prev;
502 _bytes_free -= bytes;
505 /* Set the next search to begin at this block. */
510 /* Do some of the statistics. */
512 _bytes_used -= 1 << type;
514 _bytes_free += 1 << type;
516 /* Get the address of the first free fragment in this block. */
517 prev = (struct list *) ((char *) ADDRESS(block) +
518 (_heapinfo[block].busy.info.frag.first << type));
520 if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
522 /* If all fragments of this block are free, remove them
523 from the fragment list and free the whole block. */
525 for (i = 1; i < BLOCKSIZE >> type; ++i)
527 prev->prev->next = next;
529 next->prev = prev->prev;
530 _heapinfo[block].busy.type = 0;
531 _heapinfo[block].busy.info.size = 1;
533 /* Keep the statistics accurate. */
535 _bytes_used += BLOCKSIZE;
536 _chunks_free -= BLOCKSIZE >> type;
537 _bytes_free -= BLOCKSIZE;
539 free(ADDRESS(block));
541 else if (_heapinfo[block].busy.info.frag.nfree != 0)
543 /* If some fragments of this block are free, link this
544 fragment into the fragment list after the first free
545 fragment of this block. */
546 next = (struct list *) ptr;
547 next->next = prev->next;
550 if (next->next != NULL)
551 next->next->prev = next;
552 ++_heapinfo[block].busy.info.frag.nfree;
556 /* No fragments of this block are free, so link this
557 fragment into the fragment list and announce that
558 it is the first free fragment of this block. */
559 prev = (struct list *) ptr;
560 _heapinfo[block].busy.info.frag.nfree = 1;
561 _heapinfo[block].busy.info.frag.first = (unsigned int)
562 (((char *) ptr - (char *) NULL) % BLOCKSIZE >> type);
563 prev->next = _fraghead[type].next;
564 prev->prev = &_fraghead[type];
565 prev->prev->next = prev;
566 if (prev->next != NULL)
567 prev->next->prev = prev;
573 /* Return memory to the heap. */
575 DEFUN(free, (ptr), PTR ptr)
580 if (__free_hook != NULL)
586 /* DO NOT DELETE THIS LINE -- malloc.c INSERTED HERE. */
587 /* Memory allocator `malloc'.
588 Copyright 1990 Free Software Foundation
589 Written May 1989 by Mike Haertel.
591 This program is free software; you can redistribute it and/or modify
592 it under the terms of the GNU General Public License as published by
593 the Free Software Foundation; either version 1, or (at your option)
596 This program is distributed in the hope that it will be useful,
597 but WITHOUT ANY WARRANTY; without even the implied warranty of
598 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
599 GNU General Public License for more details.
601 You should have received a copy of the GNU General Public License
602 along with this program; if not, write to the Free Software
603 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
606 or (US mail) as Mike Haertel c/o Free Software Foundation. */
609 #include "ansidecl.h"
614 #define _MALLOC_INTERNAL
616 #endif /* __ONEFILE */
618 /* How to really get more memory. */
619 PTR EXFUN((*__morecore), (ptrdiff_t __size)) = __default_morecore;
621 /* Debugging hook for `malloc'. */
622 PTR EXFUN((*__malloc_hook), (size_t __size));
624 /* Pointer to the base of the first block. */
627 /* Block information table. Allocated with align/__free (not malloc/free). */
628 malloc_info *_heapinfo;
630 /* Number of info entries. */
631 static size_t heapsize;
633 /* Search index in the info table. */
636 /* Limit of valid info table indices. */
639 /* Free lists for each fragment size. */
640 struct list _fraghead[BLOCKLOG];
642 /* Instrumentation. */
648 /* Are you experienced? */
649 int __malloc_initialized;
651 /* Aligned allocation. */
653 DEFUN(align, (size), size_t size)
658 result = (*__morecore)(size);
659 adj = (unsigned int) ((char *) result - (char *) NULL) % BLOCKSIZE;
662 adj = BLOCKSIZE - adj;
663 (void) (*__morecore)(adj);
664 result = (char *) result + adj;
669 /* Set everything up and remember that we have. */
671 DEFUN_VOID(initialize)
673 heapsize = HEAP / BLOCKSIZE;
674 _heapinfo = (malloc_info *) align(heapsize * sizeof(malloc_info));
675 if (_heapinfo == NULL)
677 memset(_heapinfo, 0, heapsize * sizeof(malloc_info));
678 _heapinfo[0].free.size = 0;
679 _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
681 _heapbase = (char *) _heapinfo;
682 __malloc_initialized = 1;
686 /* Get neatly aligned memory, initializing or
687 growing the heap info table as necessary. */
689 DEFUN(morecore, (size), size_t size)
692 malloc_info *newinfo, *oldinfo;
695 result = align(size);
699 /* Check if we need to grow the info table. */
700 if (BLOCK((char *) result + size) > heapsize)
703 while (BLOCK((char *) result + size) > newsize)
705 newinfo = (malloc_info *) align(newsize * sizeof(malloc_info));
708 (*__morecore)(- size);
711 memset(newinfo, 0, newsize * sizeof(malloc_info));
712 memcpy(newinfo, _heapinfo, heapsize * sizeof(malloc_info));
714 newinfo[BLOCK(oldinfo)].busy.type = 0;
715 newinfo[BLOCK(oldinfo)].busy.info.size
716 = BLOCKIFY(heapsize * sizeof(malloc_info));
722 _heaplimit = BLOCK((char *) result + size);
726 /* Allocate memory from the heap. */
728 DEFUN(malloc, (size), size_t size)
731 size_t block, blocks, lastblocks, start;
738 if (__malloc_hook != NULL)
739 return (*__malloc_hook)(size);
741 if (!__malloc_initialized)
745 if (size < sizeof(struct list))
746 size = sizeof(struct list);
748 /* Determine the allocation policy based on the request size. */
749 if (size <= BLOCKSIZE / 2)
751 /* Small allocation to receive a fragment of a block.
752 Determine the logarithm to base two of the fragment size. */
753 register size_t log = 1;
755 while ((size /= 2) != 0)
758 /* Look in the fragment lists for a
759 free fragment of the desired size. */
760 next = _fraghead[log].next;
763 /* There are free fragments of this size.
764 Pop a fragment out of the fragment list and return it.
765 Update the block's nfree and first counters. */
767 next->prev->next = next->next;
768 if (next->next != NULL)
769 next->next->prev = next->prev;
770 block = BLOCK(result);
771 if (--_heapinfo[block].busy.info.frag.nfree != 0)
772 _heapinfo[block].busy.info.frag.first = (unsigned int)
773 (((char *) next->next - (char *) NULL) % BLOCKSIZE) >> log;
775 /* Update the statistics. */
777 _bytes_used += 1 << log;
779 _bytes_free -= 1 << log;
783 /* No free fragments of the desired size, so get a new block
784 and break it into fragments, returning the first. */
785 result = malloc(BLOCKSIZE);
789 /* Link all fragments but the first into the free list. */
790 for (i = 1; i < BLOCKSIZE >> log; ++i)
792 next = (struct list *) ((char *) result + (i << log));
793 next->next = _fraghead[log].next;
794 next->prev = &_fraghead[log];
795 next->prev->next = next;
796 if (next->next != NULL)
797 next->next->prev = next;
800 /* Initialize the nfree and first counters for this block. */
801 block = BLOCK(result);
802 _heapinfo[block].busy.type = log;
803 _heapinfo[block].busy.info.frag.nfree = i - 1;
804 _heapinfo[block].busy.info.frag.first = i - 1;
806 _chunks_free += (BLOCKSIZE >> log) - 1;
807 _bytes_free += BLOCKSIZE - (1 << log);
812 /* Large allocation to receive one or more blocks.
813 Search the free list in a circle starting at the last place visited.
814 If we loop completely around without finding a large enough
815 space we will have to get more memory from the system. */
816 blocks = BLOCKIFY(size);
817 start = block = MALLOC_SEARCH_START;
818 while (_heapinfo[block].free.size < blocks)
820 block = _heapinfo[block].free.next;
823 /* Need to get more from the system. Check to see if
824 the new core will be contiguous with the final free
825 block; if so we don't need to get as much. */
826 block = _heapinfo[0].free.prev;
827 lastblocks = _heapinfo[block].free.size;
828 if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
829 (*__morecore)(0) == ADDRESS(block + lastblocks) &&
830 (morecore((blocks - lastblocks) * BLOCKSIZE)) != NULL)
832 _heapinfo[block].free.size = blocks;
833 _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
836 result = morecore(blocks * BLOCKSIZE);
839 block = BLOCK(result);
840 _heapinfo[block].busy.type = 0;
841 _heapinfo[block].busy.info.size = blocks;
843 _bytes_used += blocks * BLOCKSIZE;
848 /* At this point we have found a suitable free list entry.
849 Figure out how to remove what we need from the list. */
850 result = ADDRESS(block);
851 if (_heapinfo[block].free.size > blocks)
853 /* The block we found has a bit left over,
854 so relink the tail end back into the free list. */
855 _heapinfo[block + blocks].free.size
856 = _heapinfo[block].free.size - blocks;
857 _heapinfo[block + blocks].free.next
858 = _heapinfo[block].free.next;
859 _heapinfo[block + blocks].free.prev
860 = _heapinfo[block].free.prev;
861 _heapinfo[_heapinfo[block].free.prev].free.next
862 = _heapinfo[_heapinfo[block].free.next].free.prev
863 = _heapindex = block + blocks;
867 /* The block exactly matches our requirements,
868 so just remove it from the list. */
869 _heapinfo[_heapinfo[block].free.next].free.prev
870 = _heapinfo[block].free.prev;
871 _heapinfo[_heapinfo[block].free.prev].free.next
872 = _heapindex = _heapinfo[block].free.next;
876 _heapinfo[block].busy.type = 0;
877 _heapinfo[block].busy.info.size = blocks;
879 _bytes_used += blocks * BLOCKSIZE;
880 _bytes_free -= blocks * BLOCKSIZE;
886 /* DO NOT DELETE THIS LINE -- realloc.c INSERTED HERE. */
887 /* Change the size of a block allocated by `malloc'.
888 Copyright 1990 Free Software Foundation
889 Written May 1989 by Mike Haertel.
891 This program is free software; you can redistribute it and/or modify
892 it under the terms of the GNU General Public License as published by
893 the Free Software Foundation; either version 1, or (at your option)
896 This program is distributed in the hope that it will be useful,
897 but WITHOUT ANY WARRANTY; without even the implied warranty of
898 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
899 GNU General Public License for more details.
901 You should have received a copy of the GNU General Public License
902 along with this program; if not, write to the Free Software
903 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
906 or (US mail) as Mike Haertel c/o Free Software Foundation. */
909 #include "ansidecl.h"
913 #define _MALLOC_INTERNAL
915 #endif /* __ONEFILE */
917 #define MIN(A, B) ((A) < (B) ? (A) : (B))
919 /* Debugging hook for realloc. */
920 PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
922 /* Resize the given region to the new size, returning a pointer
923 to the (possibly moved) region. This is optimized for speed;
924 some benchmarks seem to indicate that greater compactness is
925 achieved by unconditionally allocating and copying to a
926 new region. This module has incestuous knowledge of the
927 internals of both free and malloc. */
929 DEFUN(realloc, (ptr, size), PTR ptr AND size_t size)
933 size_t block, blocks, oldlimit;
940 else if (ptr == NULL)
943 if (__realloc_hook != NULL)
944 return (*__realloc_hook)(ptr, size);
948 type = _heapinfo[block].busy.type;
952 /* Maybe reallocate a large block to a small fragment. */
953 if (size <= BLOCKSIZE / 2)
955 result = malloc(size);
958 memcpy(result, ptr, size);
964 /* The new size is a large allocation as well;
965 see if we can hold it in place. */
966 blocks = BLOCKIFY(size);
967 if (blocks < _heapinfo[block].busy.info.size)
969 /* The new size is smaller; return
970 excess memory to the free list. */
971 _heapinfo[block + blocks].busy.type = 0;
972 _heapinfo[block + blocks].busy.info.size
973 = _heapinfo[block].busy.info.size - blocks;
974 _heapinfo[block].busy.info.size = blocks;
975 free(ADDRESS(block + blocks));
978 else if (blocks == _heapinfo[block].busy.info.size)
979 /* No size change necessary. */
983 /* Won't fit, so allocate a new region that will.
984 Free the old region first in case there is sufficient
985 adjacent free space to grow without moving. */
986 blocks = _heapinfo[block].busy.info.size;
987 /* Prevent free from actually returning memory to the system. */
988 oldlimit = _heaplimit;
991 _heaplimit = oldlimit;
992 result = malloc(size);
995 (void) malloc(blocks * BLOCKSIZE);
999 memmove(result, ptr, blocks * BLOCKSIZE);
1004 /* Old size is a fragment; type is logarithm
1005 to base two of the fragment size. */
1006 if (size > 1 << (type - 1) && size <= 1 << type)
1007 /* The new size is the same kind of fragment. */
1011 /* The new size is different; allocate a new space,
1012 and copy the lesser of the new size and the old. */
1013 result = malloc(size);
1016 memcpy(result, ptr, MIN(size, 1 << type));
1025 /* DO NOT DELETE THIS LINE -- unix.c INSERTED HERE. */
1026 /* unix.c - get more memory with a UNIX system call.
1027 Copyright 1990 Free Software Foundation
1028 Written May 1989 by Mike Haertel.
1030 This program is free software; you can redistribute it and/or modify
1031 it under the terms of the GNU General Public License as published by
1032 the Free Software Foundation; either version 1, or (at your option)
1035 This program is distributed in the hope that it will be useful,
1036 but WITHOUT ANY WARRANTY; without even the implied warranty of
1037 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1038 GNU General Public License for more details.
1040 You should have received a copy of the GNU General Public License
1041 along with this program; if not, write to the Free Software
1042 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1045 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1048 #include "ansidecl.h"
1051 #define _MALLOC_INTERNAL
1053 #endif /* __ONEFILE */
1055 extern PTR EXFUN(sbrk, (ptrdiff_t size));
1058 DEFUN(__default_morecore, (size), ptrdiff_t size)
1062 result = sbrk(size);
1063 if (result == (PTR) -1)
1068 #define __getpagesize getpagesize
1069 /* DO NOT DELETE THIS LINE -- valloc.c INSERTED HERE. */
1070 /* Allocate memory on a page boundary.
1071 Copyright 1990 Free Software Foundation
1072 Written May 1989 by Mike Haertel.
1074 This program is free software; you can redistribute it and/or modify
1075 it under the terms of the GNU General Public License as published by
1076 the Free Software Foundation; either version 1, or (at your option)
1079 This program is distributed in the hope that it will be useful,
1080 but WITHOUT ANY WARRANTY; without even the implied warranty of
1081 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1082 GNU General Public License for more details.
1084 You should have received a copy of the GNU General Public License
1085 along with this program; if not, write to the Free Software
1086 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1089 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1092 #include "ansidecl.h"
1094 #endif /* __ONEFILE */
1096 extern size_t EXFUN(__getpagesize, (NOARGS));
1098 static size_t pagesize;
1101 DEFUN(valloc, (size), size_t size)
1107 pagesize = __getpagesize();
1109 result = malloc(size + pagesize);
1112 adj = (unsigned int) ((char *) result - (char *) NULL) % pagesize;
1114 result = (char *) result + pagesize - adj;