home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / MALLOC / EXPAND.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  1.6 KB  |  71 lines

  1. /* expand.c (emx+gcc) -- Copyright (c) 1990-1993 by Eberhard Mattes */
  2.  
  3. #include <sys/emx.h>
  4. #include <stdlib.h>
  5.  
  6. #define MAX_SIZE   0x40000000
  7.  
  8. void *_expand (void *mem, size_t size)
  9. {
  10.   void *p;
  11.  
  12.   HEAP_LOCK;
  13.   p = _expand2 (mem, size);
  14.   HEAP_UNLOCK;
  15.   return (p);
  16. }
  17.  
  18.  
  19. void *_expand2 (void *mem, size_t size)
  20. {
  21.   size_t in_use, len, xlen;
  22.   size_t *base, *block;
  23.   void *p;
  24.  
  25.   if (size > MAX_SIZE)
  26.     return (NULL);
  27.   size = (size+3) & ~3;
  28.   base = mem;
  29.   --base;
  30.   in_use = *base;
  31. restart:
  32.   *base &= ~3;                  /* temporarily in-use */
  33.   len = *base;
  34.   for (;;)
  35.     {
  36.       block = (size_t *)((char *)base + sizeof (size_t) + len);
  37.       if (block == rover)
  38.         rover = base;           /* avoid invalid rover */
  39.       xlen = *block;
  40.       if (!(xlen & 1))          /* block in use? */
  41.         break;                  /* yes -> end of contiguous area */
  42.       len += sizeof (size_t) + (xlen & ~3);
  43.     }
  44.   if (len >= size)
  45.     goto success;
  46.   *base = (len & ~3) | (in_use & 1);
  47.   if (*block != END_OF_HEAP)
  48.     return (NULL);
  49.   xlen = (size-len + sizeof (size_t) + 0xfff) & ~0xfff;
  50.   p = sbrk (xlen);
  51.   if (p == (void *)(-1))
  52.     return (NULL);
  53.   if (p != top+1)
  54.     return (NULL);
  55.   *top = (xlen - sizeof (size_t)) | 1;
  56.   top = (size_t *)((char *)top + xlen);
  57.   *top = END_OF_HEAP;
  58.   goto restart;
  59.  
  60. success:
  61.   if (len - size > sizeof (size_t))
  62.     {
  63.       block = (size_t *)((char *)base + sizeof (size_t) + size);
  64.       *block = (len - size - sizeof (size_t)) | 1;
  65.       len = size;
  66.     }
  67.   *base = (len & ~3) | (in_use & 1);
  68.   ++base;
  69.   return (base);
  70. }
  71.