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