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