Annotation of 43BSDReno/contrib/emacs-18.55/src/malloc.c, revision 1.1.1.1

1.1       root        1: /* dynamic memory allocation for GNU.
                      2:    Copyright (C) 1985, 1987 Free Software Foundation, Inc.
                      3: 
                      4:                       NO WARRANTY
                      5: 
                      6:   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
                      7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
                      8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
                      9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
                     10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
                     11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
                     12: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
                     13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
                     14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
                     15: CORRECTION.
                     16: 
                     17:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
                     18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
                     19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
                     20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
                     21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
                     22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
                     23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
                     24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
                     25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
                     26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
                     27: 
                     28:                GENERAL PUBLIC LICENSE TO COPY
                     29: 
                     30:   1. You may copy and distribute verbatim copies of this source file
                     31: as you receive it, in any medium, provided that you conspicuously and
                     32: appropriately publish on each copy a valid copyright notice "Copyright
                     33: (C) 1985 Free Software Foundation, Inc."; and include following the
                     34: copyright notice a verbatim copy of the above disclaimer of warranty
                     35: and of this License.  You may charge a distribution fee for the
                     36: physical act of transferring a copy.
                     37: 
                     38:   2. You may modify your copy or copies of this source file or
                     39: any portion of it, and copy and distribute such modifications under
                     40: the terms of Paragraph 1 above, provided that you also do the following:
                     41: 
                     42:     a) cause the modified files to carry prominent notices stating
                     43:     that you changed the files and the date of any change; and
                     44: 
                     45:     b) cause the whole of any work that you distribute or publish,
                     46:     that in whole or in part contains or is a derivative of this
                     47:     program or any part thereof, to be licensed at no charge to all
                     48:     third parties on terms identical to those contained in this
                     49:     License Agreement (except that you may choose to grant more extensive
                     50:     warranty protection to some or all third parties, at your option).
                     51: 
                     52:     c) You may charge a distribution fee for the physical act of
                     53:     transferring a copy, and you may at your option offer warranty
                     54:     protection in exchange for a fee.
                     55: 
                     56: Mere aggregation of another unrelated program with this program (or its
                     57: derivative) on a volume of a storage or distribution medium does not bring
                     58: the other program under the scope of these terms.
                     59: 
                     60:   3. You may copy and distribute this program (or a portion or derivative
                     61: of it, under Paragraph 2) in object code or executable form under the terms
                     62: of Paragraphs 1 and 2 above provided that you also do one of the following:
                     63: 
                     64:     a) accompany it with the complete corresponding machine-readable
                     65:     source code, which must be distributed under the terms of
                     66:     Paragraphs 1 and 2 above; or,
                     67: 
                     68:     b) accompany it with a written offer, valid for at least three
                     69:     years, to give any third party free (except for a nominal
                     70:     shipping charge) a complete machine-readable copy of the
                     71:     corresponding source code, to be distributed under the terms of
                     72:     Paragraphs 1 and 2 above; or,
                     73: 
                     74:     c) accompany it with the information you received as to where the
                     75:     corresponding source code may be obtained.  (This alternative is
                     76:     allowed only for noncommercial distribution and only if you
                     77:     received the program in object code or executable form alone.)
                     78: 
                     79: For an executable file, complete source code means all the source code for
                     80: all modules it contains; but, as a special exception, it need not include
                     81: source code for modules which are standard libraries that accompany the
                     82: operating system on which the executable file runs.
                     83: 
                     84:   4. You may not copy, sublicense, distribute or transfer this program
                     85: except as expressly provided under this License Agreement.  Any attempt
                     86: otherwise to copy, sublicense, distribute or transfer this program is void and
                     87: your rights to use the program under this License agreement shall be
                     88: automatically terminated.  However, parties who have received computer
                     89: software programs from you with this License Agreement will not have
                     90: their licenses terminated so long as such parties remain in full compliance.
                     91: 
                     92:   5. If you wish to incorporate parts of this program into other free
                     93: programs whose distribution conditions are different, write to the Free
                     94: Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
                     95: worked out a simple rule that can be stated here, but we will often permit
                     96: this.  We will be guided by the two goals of preserving the free status of
                     97: all derivatives of our free software and of promoting the sharing and reuse of
                     98: software.
                     99: 
                    100: 
                    101: In other words, you are welcome to use, share and improve this program.
                    102: You are forbidden to forbid anyone else to use, share and improve
                    103: what you give them.   Help stamp out software-hoarding!  */
                    104: 
                    105: 
                    106: /*
                    107:  * @(#)nmalloc.c 1 (Caltech) 2/21/82
                    108:  *
                    109:  *     U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
                    110:  *
                    111:  *     Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
                    112:  *
                    113:  * This is a very fast storage allocator.  It allocates blocks of a small 
                    114:  * number of different sizes, and keeps free lists of each size.  Blocks
                    115:  * that don't exactly fit are passed up to the next larger size.  In this 
                    116:  * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
                    117:  * This is designed for use in a program that uses vast quantities of
                    118:  * memory, but bombs when it runs out.  To make it a little better, it
                    119:  * warns the user when he starts to get near the end.
                    120:  *
                    121:  * June 84, ACT: modified rcheck code to check the range given to malloc,
                    122:  * rather than the range determined by the 2-power used.
                    123:  *
                    124:  * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
                    125:  * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
                    126:  * You should call malloc_init to reinitialize after loading dumped Emacs.
                    127:  * Call malloc_stats to get info on memory stats if MSTATS turned on.
                    128:  * realloc knows how to return same block given, just changing its size,
                    129:  * if the power of 2 is correct.
                    130:  */
                    131: 
                    132: /*
                    133:  * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
                    134:  * smallest allocatable block is 8 bytes.  The overhead information will
                    135:  * go in the first int of the block, and the returned pointer will point
                    136:  * to the second.
                    137:  *
                    138: #ifdef MSTATS
                    139:  * nmalloc[i] is the difference between the number of mallocs and frees
                    140:  * for a given block size.
                    141: #endif MSTATS
                    142:  */
                    143: 
                    144: #ifdef emacs
                    145: /* config.h specifies which kind of system this is.  */
                    146: #include "config.h"
                    147: #else
                    148: 
                    149: /* Determine which kind of system this is.  */
                    150: #include <signal.h>
                    151: #ifndef SIGTSTP
                    152: #ifndef VMS
                    153: #ifndef USG
                    154: #define USG
                    155: #endif
                    156: #endif /* not VMS */
                    157: #else /* SIGTSTP */
                    158: #ifdef SIGIO
                    159: #define BSD4_2
                    160: #endif /* SIGIO */
                    161: #endif /* SIGTSTP */
                    162: 
                    163: #endif /* not emacs */
                    164: 
                    165: /* Define getpagesize () if the system does not.  */
                    166: #include "getpagesize.h"
                    167: 
                    168: #ifndef BSD4_2
                    169: #ifndef USG
                    170: #include <sys/vlimit.h>                /* warn the user when near the end */
                    171: #endif /* not USG */
                    172: #else /* if BSD4_2 */
                    173: #include <sys/time.h>
                    174: #include <sys/resource.h>
                    175: #endif /* BSD4_2 */
                    176: 
                    177: extern char *start_of_data ();
                    178: 
                    179: #ifdef BSD
                    180: #ifndef DATA_SEG_BITS
                    181: #define start_of_data() &etext
                    182: #endif
                    183: #endif
                    184: 
                    185: #ifndef emacs
                    186: #define start_of_data() &etext
                    187: #endif
                    188: 
                    189: #define ISALLOC ((char) 0xf7)  /* magic byte that implies allocation */
                    190: #define ISFREE ((char) 0x54)   /* magic byte that implies free block */
                    191:                                /* this is for error checking only */
                    192: #define ISMEMALIGN ((char) 0xd6)  /* Stored before the value returned by
                    193:                                     memalign, with the rest of the word
                    194:                                     being the distance to the true
                    195:                                     beginning of the block.  */
                    196: 
                    197: extern char etext;
                    198: 
                    199: /* These two are for user programs to look at, when they are interested.  */
                    200: 
                    201: unsigned int malloc_sbrk_used;       /* amount of data space used now */
                    202: unsigned int malloc_sbrk_unused;     /* amount more we can have */
                    203: 
                    204: /* start of data space; can be changed by calling init_malloc */
                    205: static char *data_space_start;
                    206: 
                    207: #ifdef MSTATS
                    208: static int nmalloc[30];
                    209: static int nmal, nfre;
                    210: #endif /* MSTATS */
                    211: 
                    212: /* If range checking is not turned on, all we have is a flag indicating
                    213:    whether memory is allocated, an index in nextf[], and a size field; to
                    214:    realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
                    215:    on whether the former can hold the exact size (given the value of
                    216:    'index').  If range checking is on, we always need to know how much space
                    217:    is allocated, so the 'size' field is never used. */
                    218: 
                    219: struct mhead {
                    220:        char     mh_alloc;      /* ISALLOC or ISFREE */
                    221:        char     mh_index;      /* index in nextf[] */
                    222: /* Remainder are valid only when block is allocated */
                    223:        unsigned short mh_size; /* size, if < 0x10000 */
                    224: #ifdef rcheck
                    225:        unsigned mh_nbytes;     /* number of bytes allocated */
                    226:        int      mh_magic4;     /* should be == MAGIC4 */
                    227: #endif /* rcheck */
                    228: };
                    229: 
                    230: /* Access free-list pointer of a block.
                    231:   It is stored at block + 4.
                    232:   This is not a field in the mhead structure
                    233:   because we want sizeof (struct mhead)
                    234:   to describe the overhead for when the block is in use,
                    235:   and we do not want the free-list pointer to count in that.  */
                    236: 
                    237: #define CHAIN(a) \
                    238:   (*(struct mhead **) (sizeof (char *) + (char *) (a)))
                    239: 
                    240: #ifdef rcheck
                    241: 
                    242: /* To implement range checking, we write magic values in at the beginning and
                    243:    end of each allocated block, and make sure they are undisturbed whenever a
                    244:    free or a realloc occurs. */
                    245: /* Written in each of the 4 bytes following the block's real space */
                    246: #define MAGIC1 0x55
                    247: /* Written in the 4 bytes before the block's real space */
                    248: #define MAGIC4 0x55555555
                    249: #define ASSERT(p) if (!(p)) botch("p"); else
                    250: #define EXTRA  4               /* 4 bytes extra for MAGIC1s */
                    251: #else
                    252: #define ASSERT(p)
                    253: #define EXTRA  0
                    254: #endif /* rcheck */
                    255: 
                    256: 
                    257: /* nextf[i] is free list of blocks of size 2**(i + 3)  */
                    258: 
                    259: static struct mhead *nextf[30];
                    260: 
                    261: /* busy[i] is nonzero while allocation of block size i is in progress.  */
                    262: 
                    263: static char busy[30];
                    264: 
                    265: /* Number of bytes of writable memory we can expect to be able to get */
                    266: static unsigned int lim_data;
                    267: 
                    268: /* Level number of warnings already issued.
                    269:   0 -- no warnings issued.
                    270:   1 -- 75% warning already issued.
                    271:   2 -- 85% warning already issued.
                    272: */
                    273: static int warnlevel;
                    274: 
                    275: /* Function to call to issue a warning;
                    276:    0 means don't issue them.  */
                    277: static void (*warnfunction) ();
                    278: 
                    279: /* nonzero once initial bunch of free blocks made */
                    280: static int gotpool;
                    281: 
                    282: char *_malloc_base;
                    283: 
                    284: static void getpool ();
                    285: 
                    286: /* Cause reinitialization based on job parameters;
                    287:   also declare where the end of pure storage is. */
                    288: void
                    289: malloc_init (start, warnfun)
                    290:      char *start;
                    291:      void (*warnfun) ();
                    292: {
                    293:   if (start)
                    294:     data_space_start = start;
                    295:   lim_data = 0;
                    296:   warnlevel = 0;
                    297:   warnfunction = warnfun;
                    298: }
                    299: 
                    300: /* Return the maximum size to which MEM can be realloc'd
                    301:    without actually requiring copying.  */
                    302: 
                    303: int
                    304: malloc_usable_size (mem)
                    305:      char *mem;
                    306: {
                    307:   int blocksize = 8 << (((struct mhead *) mem) - 1) -> mh_index;
                    308: 
                    309:   return blocksize - sizeof (struct mhead) - EXTRA;
                    310: }
                    311: 
                    312: static void
                    313: morecore (nu)                  /* ask system for more memory */
                    314:      register int nu;          /* size index to get more of  */
                    315: {
                    316:   char *sbrk ();
                    317:   register char *cp;
                    318:   register int nblks;
                    319:   register unsigned int siz;
                    320:   int oldmask;
                    321: 
                    322: #ifdef BSD
                    323: #ifndef BSD4_1
                    324:   /* ?? There was a suggestion not to block SIGILL, somehow for GDB's sake.  */
                    325:   oldmask = sigsetmask (-1);
                    326: #endif
                    327: #endif
                    328: 
                    329:   if (!data_space_start)
                    330:     {
                    331:       data_space_start = start_of_data ();
                    332:     }
                    333: 
                    334:   if (lim_data == 0)
                    335:     get_lim_data ();
                    336: 
                    337:  /* On initial startup, get two blocks of each size up to 1k bytes */
                    338:   if (!gotpool)
                    339:     { getpool (); getpool (); gotpool = 1; }
                    340: 
                    341:   /* Find current end of memory and issue warning if getting near max */
                    342: 
                    343: #ifndef VMS
                    344:   /* Maximum virtual memory on VMS is difficult to calculate since it
                    345:    * depends on several dynmacially changing things. Also, alignment
                    346:    * isn't that important. That is why much of the code here is ifdef'ed
                    347:    * out for VMS systems.
                    348:    */
                    349:   cp = sbrk (0);
                    350:   siz = cp - data_space_start;
                    351: 
                    352:   if (warnfunction)
                    353:     switch (warnlevel)
                    354:       {
                    355:       case 0: 
                    356:        if (siz > (lim_data / 4) * 3)
                    357:          {
                    358:            warnlevel++;
                    359:            (*warnfunction) ("Warning: past 75% of memory limit");
                    360:          }
                    361:        break;
                    362:       case 1: 
                    363:        if (siz > (lim_data / 20) * 17)
                    364:          {
                    365:            warnlevel++;
                    366:            (*warnfunction) ("Warning: past 85% of memory limit");
                    367:          }
                    368:        break;
                    369:       case 2: 
                    370:        if (siz > (lim_data / 20) * 19)
                    371:          {
                    372:            warnlevel++;
                    373:            (*warnfunction) ("Warning: past 95% of memory limit");
                    374:          }
                    375:        break;
                    376:       }
                    377: 
                    378:   if ((int) cp & 0x3ff)        /* land on 1K boundaries */
                    379:     sbrk (1024 - ((int) cp & 0x3ff));
                    380: #endif /* not VMS */
                    381: 
                    382:  /* Take at least 2k, and figure out how many blocks of the desired size
                    383:     we're about to get */
                    384:   nblks = 1;
                    385:   if ((siz = nu) < 8)
                    386:     nblks = 1 << ((siz = 8) - nu);
                    387: 
                    388:   if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
                    389:     {
                    390: #ifdef BSD
                    391: #ifndef BSD4_1
                    392:       sigsetmask (oldmask);
                    393: #endif
                    394: #endif
                    395:       return;                  /* no more room! */
                    396:     }
                    397:   malloc_sbrk_used = siz;
                    398:   malloc_sbrk_unused = lim_data - siz;
                    399: 
                    400: #ifndef VMS
                    401:   if ((int) cp & 7)
                    402:     {          /* shouldn't happen, but just in case */
                    403:       cp = (char *) (((int) cp + 8) & ~7);
                    404:       nblks--;
                    405:     }
                    406: #endif /* not VMS */
                    407: 
                    408:  /* save new header and link the nblks blocks together */
                    409:   nextf[nu] = (struct mhead *) cp;
                    410:   siz = 1 << (nu + 3);
                    411:   while (1)
                    412:     {
                    413:       ((struct mhead *) cp) -> mh_alloc = ISFREE;
                    414:       ((struct mhead *) cp) -> mh_index = nu;
                    415:       if (--nblks <= 0) break;
                    416:       CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
                    417:       cp += siz;
                    418:     }
                    419:   CHAIN ((struct mhead *) cp) = 0;
                    420: 
                    421: #ifdef BSD
                    422: #ifndef BSD4_1
                    423:   sigsetmask (oldmask);
                    424: #endif
                    425: #endif
                    426: }
                    427: 
                    428: static void
                    429: getpool ()
                    430: {
                    431:   register int nu;
                    432:   char * sbrk ();
                    433:   register char *cp = sbrk (0);
                    434: 
                    435:   if ((int) cp & 0x3ff)        /* land on 1K boundaries */
                    436:     sbrk (1024 - ((int) cp & 0x3ff));
                    437: 
                    438:   /* Record address of start of space allocated by malloc.  */
                    439:   if (_malloc_base == 0)
                    440:     _malloc_base = cp;
                    441: 
                    442:   /* Get 2k of storage */
                    443: 
                    444:   cp = sbrk (04000);
                    445:   if (cp == (char *) -1)
                    446:     return;
                    447: 
                    448:   /* Divide it into an initial 8-word block
                    449:      plus one block of size 2**nu for nu = 3 ... 10.  */
                    450: 
                    451:   CHAIN (cp) = nextf[0];
                    452:   nextf[0] = (struct mhead *) cp;
                    453:   ((struct mhead *) cp) -> mh_alloc = ISFREE;
                    454:   ((struct mhead *) cp) -> mh_index = 0;
                    455:   cp += 8;
                    456: 
                    457:   for (nu = 0; nu < 7; nu++)
                    458:     {
                    459:       CHAIN (cp) = nextf[nu];
                    460:       nextf[nu] = (struct mhead *) cp;
                    461:       ((struct mhead *) cp) -> mh_alloc = ISFREE;
                    462:       ((struct mhead *) cp) -> mh_index = nu;
                    463:       cp += 8 << nu;
                    464:     }
                    465: }
                    466: 
                    467: char *
                    468: malloc (n)             /* get a block */
                    469:      unsigned n;
                    470: {
                    471:   register struct mhead *p;
                    472:   register unsigned int nbytes;
                    473:   register int nunits = 0;
                    474: 
                    475:   /* Figure out how many bytes are required, rounding up to the nearest
                    476:      multiple of 8, then figure out which nestf[] area to use.
                    477:      Both the beginning of the header and the beginning of the
                    478:      block should be on an eight byte boundary.  */
                    479:   nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
                    480:   {
                    481:     register unsigned int   shiftr = (nbytes - 1) >> 2;
                    482: 
                    483:     while (shiftr >>= 1)
                    484:       nunits++;
                    485:   }
                    486: 
                    487:   /* In case this is reentrant use of malloc from signal handler,
                    488:      pick a block size that no other malloc level is currently
                    489:      trying to allocate.  That's the easiest harmless way not to
                    490:      interfere with the other level of execution.  */
                    491:   while (busy[nunits]) nunits++;
                    492:   busy[nunits] = 1;
                    493: 
                    494:   /* If there are no blocks of the appropriate size, go get some */
                    495:   /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
                    496:   if (nextf[nunits] == 0)
                    497:     morecore (nunits);
                    498: 
                    499:   /* Get one block off the list, and set the new list head */
                    500:   if ((p = nextf[nunits]) == 0)
                    501:     {
                    502:       busy[nunits] = 0;
                    503:       return 0;
                    504:     }
                    505:   nextf[nunits] = CHAIN (p);
                    506:   busy[nunits] = 0;
                    507: 
                    508:   /* Check for free block clobbered */
                    509:   /* If not for this check, we would gobble a clobbered free chain ptr */
                    510:   /* and bomb out on the NEXT allocate of this size block */
                    511:   if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
                    512: #ifdef rcheck
                    513:     botch ("block on free list clobbered");
                    514: #else /* not rcheck */
                    515:     abort ();
                    516: #endif /* not rcheck */
                    517: 
                    518:   /* Fill in the info, and if range checking, set up the magic numbers */
                    519:   p -> mh_alloc = ISALLOC;
                    520: #ifdef rcheck
                    521:   p -> mh_nbytes = n;
                    522:   p -> mh_magic4 = MAGIC4;
                    523:   {
                    524:     /* Get the location n after the beginning of the user's space.  */
                    525:     register char *m = (char *) p + ((sizeof *p + 7) & ~7) + n;
                    526: 
                    527:     *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
                    528:   }
                    529: #else /* not rcheck */
                    530:   p -> mh_size = n;
                    531: #endif /* not rcheck */
                    532: #ifdef MSTATS
                    533:   nmalloc[nunits]++;
                    534:   nmal++;
                    535: #endif /* MSTATS */
                    536:   return (char *) p + ((sizeof *p + 7) & ~7);
                    537: }
                    538: 
                    539: free (mem)
                    540:      char *mem;
                    541: {
                    542:   register struct mhead *p;
                    543:   {
                    544:     register char *ap = mem;
                    545: 
                    546:     if (ap == 0)
                    547:       return;
                    548: 
                    549:     p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
                    550:     if (p -> mh_alloc == ISMEMALIGN)
                    551:       {
                    552:        ap -= p->mh_size;
                    553:        p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
                    554:       }
                    555: 
                    556: #ifndef rcheck
                    557:     if (p -> mh_alloc != ISALLOC)
                    558:       abort ();
                    559: 
                    560: #else rcheck
                    561:     if (p -> mh_alloc != ISALLOC)
                    562:       {
                    563:        if (p -> mh_alloc == ISFREE)
                    564:          botch ("free: Called with already freed block argument\n");
                    565:        else
                    566:          botch ("free: Called with bad argument\n");
                    567:       }
                    568: 
                    569:     ASSERT (p -> mh_magic4 == MAGIC4);
                    570:     ap += p -> mh_nbytes;
                    571:     ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
                    572:     ASSERT (*ap++ == MAGIC1); ASSERT (*ap   == MAGIC1);
                    573: #endif /* rcheck */
                    574:   }
                    575:   {
                    576:     register int nunits = p -> mh_index;
                    577: 
                    578:     ASSERT (nunits <= 29);
                    579:     p -> mh_alloc = ISFREE;
                    580: 
                    581:     /* Protect against signal handlers calling malloc.  */
                    582:     busy[nunits] = 1;
                    583:     /* Put this block on the free list.  */
                    584:     CHAIN (p) = nextf[nunits];
                    585:     nextf[nunits] = p;
                    586:     busy[nunits] = 0;
                    587: 
                    588: #ifdef MSTATS
                    589:     nmalloc[nunits]--;
                    590:     nfre++;
                    591: #endif /* MSTATS */
                    592:   }
                    593: }
                    594: 
                    595: char *
                    596: realloc (mem, n)
                    597:      char *mem;
                    598:      register unsigned n;
                    599: {
                    600:   register struct mhead *p;
                    601:   register unsigned int tocopy;
                    602:   register unsigned int nbytes;
                    603:   register int nunits;
                    604: 
                    605:   if (mem == 0)
                    606:     return malloc (n);
                    607:   p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7));
                    608:   nunits = p -> mh_index;
                    609:   ASSERT (p -> mh_alloc == ISALLOC);
                    610: #ifdef rcheck
                    611:   ASSERT (p -> mh_magic4 == MAGIC4);
                    612:   {
                    613:     register char *m = mem + (tocopy = p -> mh_nbytes);
                    614:     ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
                    615:     ASSERT (*m++ == MAGIC1); ASSERT (*m   == MAGIC1);
                    616:   }
                    617: #else /* not rcheck */
                    618:   if (p -> mh_index >= 13)
                    619:     tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7);
                    620:   else
                    621:     tocopy = p -> mh_size;
                    622: #endif /* not rcheck */
                    623: 
                    624:   /* See if desired size rounds to same power of 2 as actual size. */
                    625:   nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
                    626: 
                    627:   /* If ok, use the same block, just marking its size as changed.  */
                    628:   if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
                    629:     {
                    630: #ifdef rcheck
                    631:       register char *m = mem + tocopy;
                    632:       *m++ = 0;  *m++ = 0;  *m++ = 0;  *m++ = 0;
                    633:       p-> mh_nbytes = n;
                    634:       m = mem + n;
                    635:       *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;
                    636: #else /* not rcheck */
                    637:       p -> mh_size = n;
                    638: #endif /* not rcheck */
                    639:       return mem;
                    640:     }
                    641: 
                    642:   if (n < tocopy)
                    643:     tocopy = n;
                    644:   {
                    645:     register char *new;
                    646: 
                    647:     if ((new = malloc (n)) == 0)
                    648:       return 0;
                    649:     bcopy (mem, new, tocopy);
                    650:     free (mem);
                    651:     return new;
                    652:   }
                    653: }
                    654: 
                    655: #ifndef VMS
                    656: 
                    657: char *
                    658: memalign (alignment, size)
                    659:      unsigned alignment, size;
                    660: {
                    661:   register char *ptr = malloc (size + alignment);
                    662:   register char *aligned;
                    663:   register struct mhead *p;
                    664: 
                    665:   if (ptr == 0)
                    666:     return 0;
                    667:   /* If entire block has the desired alignment, just accept it.  */
                    668:   if (((int) ptr & (alignment - 1)) == 0)
                    669:     return ptr;
                    670:   /* Otherwise, get address of byte in the block that has that alignment.  */
                    671:   aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
                    672: 
                    673:   /* Store a suitable indication of how to free the block,
                    674:      so that free can find the true beginning of it.  */
                    675:   p = (struct mhead *) aligned - 1;
                    676:   p -> mh_size = aligned - ptr;
                    677:   p -> mh_alloc = ISMEMALIGN;
                    678:   return aligned;
                    679: }
                    680: 
                    681: #ifndef HPUX
                    682: /* This runs into trouble with getpagesize on HPUX.
                    683:    Patching out seems cleaner than the ugly fix needed.  */
                    684: char *
                    685: valloc (size)
                    686: {
                    687:   return memalign (getpagesize (), size);
                    688: }
                    689: #endif /* not HPUX */
                    690: #endif /* not VMS */
                    691: 
                    692: #ifdef MSTATS
                    693: /* Return statistics describing allocation of blocks of size 2**n. */
                    694: 
                    695: struct mstats_value
                    696:   {
                    697:     int blocksize;
                    698:     int nfree;
                    699:     int nused;
                    700:   };
                    701: 
                    702: struct mstats_value
                    703: malloc_stats (size)
                    704:      int size;
                    705: {
                    706:   struct mstats_value v;
                    707:   register int i;
                    708:   register struct mhead *p;
                    709: 
                    710:   v.nfree = 0;
                    711: 
                    712:   if (size < 0 || size >= 30)
                    713:     {
                    714:       v.blocksize = 0;
                    715:       v.nused = 0;
                    716:       return v;
                    717:     }
                    718: 
                    719:   v.blocksize = 1 << (size + 3);
                    720:   v.nused = nmalloc[size];
                    721: 
                    722:   for (p = nextf[size]; p; p = CHAIN (p))
                    723:     v.nfree++;
                    724: 
                    725:   return v;
                    726: }
                    727: int
                    728: malloc_mem_used ()
                    729: {
                    730:   int i;
                    731:   int size_used;
                    732: 
                    733:   size_used = 0;
                    734:   
                    735:   for (i = 0; i < 30; i++)
                    736:     {
                    737:       int allocation_size = 1 << (i + 3);
                    738:       struct mhead *p;
                    739:       
                    740:       size_used += nmalloc[i] * allocation_size;
                    741:     }
                    742: 
                    743:   return size_used;
                    744: }
                    745: 
                    746: int 
                    747: malloc_mem_free ()
                    748: {
                    749:   int i;
                    750:   int size_unused;
                    751: 
                    752:   size_unused = 0;
                    753:   
                    754:   for (i = 0; i < 30; i++)
                    755:     {
                    756:       int allocation_size = 1 << (i + 3);
                    757:       struct mhead *p;
                    758:       
                    759:       for (p = nextf[i]; p ; p = CHAIN (p))
                    760:        size_unused += allocation_size;
                    761:     }
                    762: 
                    763:   return size_unused;
                    764: }
                    765: #endif /* MSTATS */
                    766: 
                    767: /*
                    768:  *     This function returns the total number of bytes that the process
                    769:  *     will be allowed to allocate via the sbrk(2) system call.  On
                    770:  *     BSD systems this is the total space allocatable to stack and
                    771:  *     data.  On USG systems this is the data space only.
                    772:  */
                    773: 
                    774: #ifdef USG
                    775: 
                    776: get_lim_data ()
                    777: {
                    778:   extern long ulimit ();
                    779:     
                    780: #ifdef ULIMIT_BREAK_VALUE
                    781:   lim_data = ULIMIT_BREAK_VALUE;
                    782: #else
                    783:   lim_data = ulimit (3, 0);
                    784: #endif
                    785: 
                    786:   lim_data -= (long) data_space_start;
                    787: }
                    788: 
                    789: #else /* not USG */
                    790: #ifndef BSD4_2
                    791: 
                    792: get_lim_data ()
                    793: {
                    794:   lim_data = vlimit (LIM_DATA, -1);
                    795: }
                    796: 
                    797: #else /* BSD4_2 */
                    798: 
                    799: get_lim_data ()
                    800: {
                    801:   struct rlimit XXrlimit;
                    802: 
                    803:   getrlimit (RLIMIT_DATA, &XXrlimit);
                    804: #ifdef RLIM_INFINITY
                    805:   lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
                    806: #else
                    807:   lim_data = XXrlimit.rlim_cur;        /* soft limit */
                    808: #endif
                    809: }
                    810: 
                    811: #endif /* BSD4_2 */
                    812: #endif /* not USG */
                    813: 
                    814: #ifdef VMS
                    815: /* There is a problem when dumping and restoring things on VMS. Calls
                    816:  * to SBRK don't necessarily result in contiguous allocation. Dumping
                    817:  * doesn't work when it isn't. Therefore, we make the initial
                    818:  * allocation contiguous by allocating a big chunk, and do SBRKs from
                    819:  * there. Once Emacs has dumped there is no reason to continue
                    820:  * contiguous allocation, malloc doesn't depend on it.
                    821:  *
                    822:  * There is a further problem of using brk and sbrk while using VMS C
                    823:  * run time library routines malloc, calloc, etc. The documentation
                    824:  * says that this is a no-no, although I'm not sure why this would be
                    825:  * a problem. In any case, we remove the necessity to call brk and
                    826:  * sbrk, by calling calloc (to assure zero filled data) rather than
                    827:  * sbrk.
                    828:  *
                    829:  * VMS_ALLOCATION_SIZE is the size of the allocation array. This
                    830:  * should be larger than the malloc size before dumping. Making this
                    831:  * too large will result in the startup procedure slowing down since
                    832:  * it will require more space and time to map it in.
                    833:  *
                    834:  * The value for VMS_ALLOCATION_SIZE in the following define was determined
                    835:  * by running emacs linked (and a large allocation) with the debugger and
                    836:  * looking to see how much storage was used. The allocation was 201 pages,
                    837:  * so I rounded it up to a power of two.
                    838:  */
                    839: #ifndef VMS_ALLOCATION_SIZE
                    840: #define VMS_ALLOCATION_SIZE    (512*256)
                    841: #endif
                    842: 
                    843: /* Use VMS RTL definitions */
                    844: #undef sbrk
                    845: #undef brk
                    846: #undef malloc
                    847: int vms_out_initial = 0;
                    848: char vms_initial_buffer[VMS_ALLOCATION_SIZE];
                    849: static char *vms_current_brk = &vms_initial_buffer;
                    850: static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1];
                    851: 
                    852: #include <stdio.h>
                    853: 
                    854: char *
                    855: sys_sbrk (incr)
                    856:      int incr;
                    857: {
                    858:   char *sbrk(), *temp, *ptr;
                    859: 
                    860:   if (vms_out_initial)
                    861:     {
                    862:       /* out of initial allocation... */
                    863:       if (!(temp = malloc (incr)))
                    864:        temp = (char *) -1;
                    865:     }
                    866:   else
                    867:     {
                    868:       /* otherwise, go out of our area */
                    869:       ptr = vms_current_brk + incr; /* new current_brk */
                    870:       if (ptr <= vms_end_brk)
                    871:        {
                    872:          temp = vms_current_brk;
                    873:          vms_current_brk = ptr;
                    874:        }
                    875:       else
                    876:        {
                    877:          vms_out_initial = 1;  /* mark as out of initial allocation */
                    878:          if (!(temp = malloc (incr)))
                    879:            temp = (char *) -1;
                    880:        }
                    881:     }
                    882:   return temp;
                    883: }
                    884: #endif /* VMS */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.