home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib25.zoo / realloc.c < prev    next >
C/C++ Source or Header  |  1992-09-05  |  2KB  |  96 lines

  1. /* from the TOS GCC library */
  2. /* malloc, free, realloc: dynamic memory allocation */
  3. /* 5/2/92 sb -- modified for Heat-n-Serve C to accomodate its 16-bit size_t */
  4. /* 5/5/92 sb -- realloc() gets its own file to reduce library drag */
  5.  
  6. #include <stddef.h>    /* for size_t */
  7. #include <stdlib.h>
  8. #include <memory.h>
  9. #include <string.h>
  10. #include <assert.h>
  11. #include <unistd.h>
  12. #include "lib.h"
  13.  
  14. __EXTERN void *_malloc __PROTO((unsigned long));
  15. __EXTERN void _bzero __PROTO((void *, unsigned long));
  16. void *_realloc __PROTO((void *, unsigned long));
  17.  
  18. #ifdef __GNUC__
  19. asm(".stabs \"_realloc\",5,0,0,__realloc"); /* dept of clean tricks */
  20. #endif
  21.  
  22. void * _realloc(_r, n)
  23. void *_r;
  24. unsigned long n;
  25. {
  26.   struct mem_chunk *p, *q, *r = (struct mem_chunk *) _r;
  27.   long sz;
  28.  
  29. /* obscure features: realloc(NULL,n) is the same as malloc(n)
  30.  *               realloc(p, 0) is the same as free(p)
  31.  */
  32.   if (!r)
  33.     return _malloc(n);
  34.   if (n == 0) {
  35.     free(_r);
  36.     return NULL;
  37.   }
  38.   p = r - 1;
  39.   sz = (n + sizeof(struct mem_chunk) + 7) & ~7;
  40.  
  41.   if (p->size > sz) 
  42.     {            /* block too big, split in two */
  43.     q = (struct mem_chunk * )(((long) p) + sz);
  44.     q->size = p->size - sz;
  45.         q->valid = VAL_ALLOC;
  46.     free(q + 1);
  47.     p->size = sz;
  48.     }
  49.     else 
  50.   if (p->size < sz)
  51.     {            /* block too small, get new one */
  52.     struct mem_chunk *s, *t;
  53.     q = &_mchunk_free_list;
  54.     t = _mchunk_free_list.next;
  55.     while (t != NULL && t < p)
  56.       {
  57.       q = t;
  58.       t = t->next;
  59.       }
  60.  
  61.     /* merge after if possible */
  62.     s = (struct mem_chunk * )(((long) p) + p->size);
  63.     if (t != NULL && s >= t && p->size + t->size >= sz)
  64.       {
  65.       assert(s == t);
  66.       p->size += t->size;
  67.       q->next = t->next;
  68.       t->size = 0;
  69.       t->next = NULL;
  70.       }
  71.     else
  72.       {
  73.       q = (struct mem_chunk * )_malloc(n);
  74.       if (q != NULL)
  75.     {
  76.     n = p->size - sizeof(struct mem_chunk);
  77.     _bcopy(r, q, n);
  78.         free(r);    /* free r only if we got a new block */
  79.         }
  80.       /* else we could try to mlalloc the rest and hope that we can merge */
  81.       r = q;
  82.     }
  83.   }
  84.   /* else current block will do just fine */
  85.   return((void * )r);
  86. }
  87.  
  88. #ifndef __GNUC__
  89. void * realloc(_r, n)
  90. void *_r;
  91. size_t n;
  92. {
  93.   return _realloc(_r, (unsigned long) n);
  94. }
  95. #endif
  96.