home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / tek / mem / staticrealloc.c < prev   
Encoding:
C/C++ Source or Header  |  2001-05-12  |  4.0 KB  |  213 lines

  1.  
  2. #include "tek/mem.h"
  3.  
  4. /* 
  5. **    TEKlib
  6. **    (C) 2001 TEK neoscientists
  7. **    all rights reserved.
  8. **
  9. **    TAPTR TStaticRealloc(TMEMHEAD *head, TAPTR mem, TUINT size)
  10. **
  11. **    reallocate allocation from static allocator.
  12. */
  13.  
  14. TAPTR TStaticRealloc(TMEMHEAD *head, TAPTR mem, TUINT size)
  15. {
  16.     if (size)
  17.     {
  18.         size = (size + head->align) & ~head->align;
  19.  
  20.         if (mem)
  21.         {
  22.             TMEMNODE *p = (TMEMNODE *) ((TUINT8 *) mem - head->memnodesize);
  23.             TUINT oldsize = p->size - p->free;
  24.  
  25.             if (size < oldsize)
  26.             {
  27.                 /* shrink */
  28.         
  29.                 if (p->next)
  30.                 {
  31.                     if (p->next->free == p->next->size)
  32.                     {
  33.                         /*    next node is free - move next node. */
  34.  
  35.                         TMEMNODE *pnnext = p->next->next;
  36.                         TUINT pnsize = p->next->size;
  37.                         TMEMNODE *n = (TMEMNODE *)((TUINT8 *)p + head->memnodesize + size);
  38.  
  39.                         head->freesize += p->size - size - p->free;
  40.                                                 
  41.                         n->prev = p;
  42.                         n->next = pnnext;
  43.                         n->size = pnsize + p->size - size;
  44.                         n->free = n->size;
  45.                         
  46.                         p->next = n;
  47.                         if (n->next)
  48.                         {
  49.                             n->next->prev = n;
  50.                         }
  51.                         
  52.                         p->size = size;
  53.                         p->free = 0;
  54.  
  55.                         return mem;
  56.                     }
  57.                     else if (p->size - size > head->memnodesize)
  58.                     {
  59.                         /* next node is not free, but there is room for a new node */
  60.                         
  61.                         TMEMNODE *n = (TMEMNODE *) ((TUINT8 *)p + head->memnodesize + size);
  62.  
  63.                         head->freesize += p->size - size - p->free - head->memnodesize;
  64.  
  65.                         n->next = p->next;
  66.                         n->prev = p;
  67.                         n->next->prev = n;
  68.                         
  69.                         n->size = p->size - size - head->memnodesize;
  70.                         n->free = n->size;
  71.             
  72.                         p->size = size;
  73.                         p->free = 0;
  74.             
  75.                         p->next = n;
  76.             
  77.                         return mem;
  78.                     }
  79.                     else
  80.                     {
  81.                         /* no room for a new node */
  82.  
  83.                         head->freesize += p->size - size - p->free;
  84.                         p->free = p->size - size;
  85.                         return mem;
  86.                     }                
  87.                 }
  88.                 else
  89.                 {
  90.                     /* endnode */
  91.  
  92.                     head->freesize -= p->free - p->size + size;
  93.                     p->free = p->size - size;
  94.                     return mem;
  95.                 }
  96.             }
  97.             else if (size > oldsize)
  98.             {
  99.                 TUINT8 *newmem;
  100.  
  101.                 /* enlarge */
  102.                 
  103.                 if (p->next)
  104.                 {
  105.                     if (p->next->size == p->next->free)
  106.                     {
  107.                         /* next node is free */
  108.         
  109.                         if (p->size + p->next->size > size)
  110.                         {
  111.                             /* move next node */
  112.     
  113.                             TUINT pnsize = p->next->size;
  114.                             TMEMNODE *pnnext = p->next->next;
  115.                             TMEMNODE *n = (TMEMNODE *)(((TUINT8 *) p) + head->memnodesize + size);
  116.  
  117.                             head->freesize -= size - p->size + p->free;
  118.  
  119.                             n->next = pnnext;
  120.                             n->prev = p;
  121.                             n->size = pnsize - size + p->size;
  122.                             n->free = n->size;
  123.                             if (pnnext)
  124.                             {
  125.                                 pnnext->prev = n;
  126.                             }
  127.                             
  128.                             p->size = size;
  129.                             p->free = 0;
  130.                             p->next = n;
  131.  
  132.                             return mem;                    
  133.                         }
  134.                         else if (p->size + p->next->size + head->memnodesize >= size)
  135.                         {
  136.                             /* eliminate next node */
  137.  
  138.                             head->freesize -= size - p->size + p->free - head->memnodesize + p->free;
  139.                         
  140.                             p->size += p->next->size + head->memnodesize;
  141.                             p->next = p->next->next;
  142.                             p->next->prev = p;    
  143.                                                         
  144.                             p->free = p->size - size;
  145.                             return mem;
  146.                         }
  147.                     }
  148.                     else if (p->free)
  149.                     {
  150.                         /* leftover in this node */
  151.                         
  152.                         if (p->size >= size)
  153.                         {
  154.                             /* sufficient */
  155.                 
  156.                             head->freesize -= p->free - p->size + size;            
  157.                             p->free = p->size - size;
  158.                             return mem;
  159.                         }
  160.                     }
  161.                 }
  162.                 else
  163.                 {
  164.                     /* endnode */
  165.                 
  166.                     if (p->size >= size)
  167.                     {
  168.                         head->freesize -= p->free - p->size + size;
  169.                         p->free = p->size - size;
  170.                         return mem;
  171.                     }
  172.                 }
  173.         
  174.                 /*
  175.                 **    last resort: try to reallocate by
  176.                 **    allocating, copying, and freeing
  177.                 */
  178.                 
  179.                 newmem = TStaticAlloc(head, size);
  180.                 if (newmem)
  181.                 {
  182.                     TMemCopy32(mem, newmem, TMIN(size, oldsize));
  183.                     TStaticFree(head, mem);
  184.                 }
  185.                 
  186.                 return newmem;                    
  187.             }
  188.             else
  189.             {
  190.                 /* size unchanged */
  191.                 return mem;
  192.             }
  193.         }
  194.         else
  195.         {
  196.             /* size, but no mem -> alloc */
  197.         
  198.             return TStaticAlloc(head, size);
  199.         }
  200.     }
  201.     else
  202.     {
  203.         /* no size */
  204.         
  205.         if (mem)
  206.         {
  207.             TStaticFree(head, mem);
  208.         }
  209.     }
  210.  
  211.     return TNULL;
  212. }
  213.