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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 The author may be reached (Email) at the address mike@ai.mit.edu,
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
406 The author may be reached (Email) at the address mike@ai.mit.edu,
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
605 The author may be reached (Email) at the address mike@ai.mit.edu,
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
905 The author may be reached (Email) at the address mike@ai.mit.edu,
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1044 The author may be reached (Email) at the address mike@ai.mit.edu,
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1088 The author may be reached (Email) at the address mike@ai.mit.edu,
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
;
This page took 0.056047 seconds and 4 git commands to generate.