home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 316 / libsrc / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  3.4 KB  |  189 lines

  1.  
  2. /* malloc, free, realloc: dynamic memory allocation */
  3.  
  4. /* minimum chunk to ask OS for */
  5. #define MINHUNK    4096
  6.  
  7. #define NULL 0
  8.  
  9. struct mem_chunk 
  10.     {
  11.     struct mem_chunk *next;
  12.     unsigned size;
  13.     };
  14.  
  15. /* linked list of free blocks */
  16.  
  17. struct mem_chunk _mchunk_free_list = { NULL, 0 };
  18.  
  19. char * malloc(n)
  20. unsigned n; 
  21. {
  22.   struct mem_chunk *p, *q;
  23.   long sz;
  24.  
  25. /* add a mem_chunk to required size and round up */
  26.   n = n + sizeof(struct mem_chunk);
  27.   n = (7 + n) & ~7;
  28. /*
  29.     sprintf(dbgbuf, "Malloc: size=%d \r\n", n);
  30.     _ps(dbgbuf);
  31. */
  32. /* look for first block big enough in free list */
  33.   p = &_mchunk_free_list;
  34. /*
  35.     sprintf(dbgbuf, "  _mchunk_free_list=%lx\r\n", p);
  36.     _ps(dbgbuf);
  37. */
  38.   q = _mchunk_free_list.next;
  39. /*
  40.     sprintf(dbgbuf, "  q=%lx\r\n", q);
  41.     _ps(dbgbuf);
  42. */
  43.   while ((q != NULL) && (q->size < n))
  44.     {
  45.     p = q;
  46.     q = q->next;
  47. /*
  48.     sprintf(dbgbuf, "  next@ %lx\r\n", q);
  49.     _ps(dbgbuf);
  50. */
  51.         }
  52.  
  53. /* if not enough memory, get more from the system */
  54.   if (q == NULL) 
  55.     {
  56.     sz = (n > MINHUNK ? n : MINHUNK);
  57. /*
  58.     sprintf(dbgbuf, "  sz %d -> ", sz);
  59.     _ps(dbgbuf);
  60. */
  61.     q = (struct mem_chunk * )trap_1_wlww(0x48, sz);
  62. /*
  63.     sprintf(dbgbuf, "%lx\r\n", q);
  64.     _ps(dbgbuf);
  65. */
  66.     if (((long)q) <= 0)         /* can't alloc any more? */
  67.         return(NULL);
  68. /*
  69.     _ps("  Ok\r\n");
  70. */
  71.     p->next = q;
  72.     q->size = sz;
  73.     q->next = NULL;
  74.     }
  75.         
  76.   if (q->size > n + sizeof(struct mem_chunk))
  77.     {                /* split, leave part of free list */
  78.     q->size -= n;
  79.     q = (struct mem_chunk * )(((long) q) + q->size);
  80.     q->size = n;
  81.     }
  82.     else
  83.     {                /* just unlink it */
  84.     p->next = q->next;
  85.     }
  86.     
  87.     /* hand back ptr to after chunk desc */
  88. /*
  89.     sprintf(dbgbuf, "  ---> %lx\r\n", q);
  90.     _ps(dbgbuf);
  91. */
  92.   return((char * )++q);
  93. }
  94.  
  95. free(r)
  96. struct mem_chunk *r;    /* not really, but it will be soon... */
  97. {
  98.   struct mem_chunk *p, *q, *t;
  99.  
  100. /* move back to uncover the mem_chunk */
  101.   r--;            /* there it is! */
  102. /*
  103.     sprintf(dbgbuf, "Mfree: %lx\r\n", r);
  104.     _ps(dbgbuf);
  105. */
  106. /* stick it into free list, preserving ascending address order */
  107.   p = &_mchunk_free_list;
  108.   q = _mchunk_free_list.next;
  109.   while (q != NULL && q < r) 
  110.     {
  111.     p = q;
  112.     q = q->next;
  113.     }
  114.  
  115. /* merge after if possible */
  116.   t = (struct mem_chunk * )(((long) r) + r->size);
  117.   if (q != NULL && t >= q) 
  118.     {
  119.     r->size += q->size;
  120.     q = q->next;
  121.     }
  122.   r->next = q;
  123.     
  124. /* merge before if possible, otherwise link it in */
  125.   t = (struct mem_chunk * )(((long) p) + p->size);
  126.   if (t >= r) 
  127.     {
  128.     p->size += r->size;
  129.     p->next = r->next;
  130.     }
  131.     else
  132.     p->next = r;
  133. }
  134.  
  135. char * realloc(r, n)
  136. struct mem_chunk *r;
  137. unsigned n;
  138. {
  139.   struct mem_chunk *p, *q;
  140.   long *src, *dst;
  141.   unsigned sz;
  142.  
  143.   p = r - 1;
  144.   sz = (n + sizeof(struct mem_chunk) + 7) & ~7;
  145.  
  146.   if (p->size > sz) 
  147.     {            /* block too big, split in two */
  148.     q = (struct mem_chunk * )(((long) p) + sz);
  149.     q->size = p->size - sz;
  150.     free(q + 1);
  151.     p->size = sz;
  152.     }
  153.     else 
  154.   if (p->size < sz)
  155.     {            /* block too small, get new one */
  156.     dst = q = (struct mem_chunk * )malloc(n);
  157.     if (q != NULL)
  158.         {
  159.         src = (long * )r;
  160.         n = p->size - sizeof(struct mem_chunk);
  161.         while (n > 0) 
  162.             {
  163.             *dst++ = *src++;
  164.             n -= sizeof(long);
  165.             }
  166.         }
  167.     free(r);
  168.     r = q;
  169.     }
  170.     /* else current block will do just fine */
  171.   return((char * )r);
  172. }
  173.  
  174. char * calloc(n, sz)
  175. unsigned n, sz;
  176. {
  177.   char *r, *s;
  178.   unsigned total;
  179.  
  180.   total = n * sz;
  181.   if ((r = s = malloc(total)) != NULL)
  182.     {
  183.     while (total--)
  184.         *s++ = 0;
  185.     }
  186.   return(r);
  187. }
  188.  
  189.