source: trunk/indexers/mg/lib/gmalloc.c@ 3745

Last change on this file since 3745 was 3745, checked in by mdewsnip, 21 years ago

Addition of MG package for search and retrieval

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