home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_06 / 1006016a < prev    next >
Text File  |  1992-04-09  |  3KB  |  77 lines

  1. /* malloc function */
  2. #include "xalloc.h"
  3. #include "yfuns.h"
  4.  
  5.                 /* static data */
  6. _Altab _Aldata = {0};   /* heap initially empty */
  7.  
  8. static _Cell **findmem(size_t size)
  9.         {       /* find storage */
  10.         _Cell *q, **qb;
  11.  
  12.         for (; ; )
  13.                 {       /* check freed space first */
  14.                 if ((qb = _Aldata._Plast) == NULL)
  15.                         {       /* take it from the top */
  16.                         for (qb = &_Aldata._Head; *qb;
  17.                                 qb = &(*qb)->_Next)
  18.                                 if (size <= (*qb)->_Size)
  19.                                         return (qb);
  20.                         }
  21.                 else
  22.                         {       /* resume where we left off */
  23.                         for (; *qb; qb = &(*qb)->_Next)
  24.                                 if (size <= (*qb)->_Size)
  25.                                         return (qb);
  26.                         q = *_Aldata._Plast;
  27.                         for (qb = &_Aldata._Head; *qb != q;
  28.                                 qb = &(*qb)->_Next)
  29.                                 if (size <= (*qb)->_Size)
  30.                                         return (qb);
  31.                         }
  32.                  {      /* try to buy more space */
  33.                 size_t bs;
  34.                 const size_t sz = size + CELL_OFF;
  35.  
  36.                 for (bs = SIZE_BLOCK; ; bs >>= 1)
  37.                         {       /* try larger blocks first */
  38.                         if (bs < sz)
  39.                                 bs = sz;
  40.                         if ((q = (_Cell *)_Getmem(bs)) != NULL)
  41.                                 break;
  42.                         else if (bs == sz)
  43.                                 return (NULL);  /* no storage */
  44.                         }
  45.                 /* got storage: add to heap and retry */
  46.                 q->_Size = (bs & ~_MEMBND) - CELL_OFF;
  47.                 free((char *)q + CELL_OFF);
  48.                  }
  49.                 }
  50.         }
  51.  
  52. void *(malloc)(size_t size)
  53.         {       /* allocate a data object on the heap */
  54.         _Cell *q, **qb;
  55.  
  56.         if (size < SIZE_CELL)  /* round up size */
  57.                 size = SIZE_CELL;
  58.         size = (size + _MEMBND) & ~_MEMBND;
  59.         if ((qb = findmem(size)) == NULL)
  60.                 return (NULL);
  61.         q = *qb;
  62.         if (q->_Size < size + CELL_OFF + SIZE_CELL)
  63.                 *qb = q->_Next;        /* use entire cell */
  64.         else
  65.                 {       /* peel off a residual cell */
  66.                 *qb = (_Cell *)((char *)q
  67.                         + CELL_OFF + size);
  68.                 (*qb)->_Next = q->_Next;
  69.                 (*qb)->_Size = q->_Size - CELL_OFF - size;
  70.                 q->_Size = size;
  71.                 }
  72.         _Aldata._Plast = qb;    /* resume here */
  73.         return ((char *)q + CELL_OFF);
  74.         }
  75.  
  76.  
  77.