home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / vbcc / machines / amiga68k / libsrc / stdlib / malloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-24  |  3.1 KB  |  117 lines

  1. #include <stdlib.h>
  2.  
  3. /*#include <exec/memory.h>*/
  4. #include <proto/exec.h>
  5. #include <proto/dos.h>
  6.  
  7. /*  stark modifizierte Version aus K&R  */
  8.  
  9. static union _mheader _base;
  10. static union _mheader *_freep=0;
  11.  
  12. size_t _nalloc=1023;
  13. union _mheader *_first_mlist=0,*_last_mlist=0;
  14.  
  15. union _mheader *_morecore(size_t anu)
  16. {
  17.     union _mheader *up;size_t nu;
  18.     if(anu<_nalloc) nu=_nalloc; else nu=anu;
  19.     up=(union _mheader *)AllocMem((nu+1)*sizeof(union _mheader),0L);
  20.     if(!up) return(0);
  21.     up->s.size=nu+1; up->s.ptr=0; /*  Merken fuer Freigabe am Schluss */
  22.     if(_last_mlist){
  23.         _last_mlist->s.ptr=up;_last_mlist=up;
  24.     }else{
  25.         _last_mlist=_first_mlist=up;
  26.     }
  27.     up++;
  28.     up->s.size=nu;
  29.     if(anu>_nalloc) return((void *)up);
  30.     free((void *)(up+1));
  31.     return(_freep);
  32. }
  33. void _freemem(void)
  34. /*  Gibt allen Speicher frei    */
  35. {
  36.     union _mheader *p=_first_mlist,*m;
  37.     while(p){
  38.         m=p->s.ptr;
  39.         FreeMem(p,p->s.size*sizeof(union _mheader));
  40.         p=m;
  41.     }
  42. }
  43. void *malloc(size_t nbytes)
  44. {
  45.     union _mheader *p,*prevp;
  46.     size_t nunits;
  47.     /*  aufrunden   */
  48.     nunits=(nbytes+sizeof(union _mheader)-1)/sizeof(union _mheader)+1;
  49.     if(nunits>_nalloc){
  50.         if(!(p=_morecore(nunits))) return(0);
  51.         p->s.size=nunits;p->s.ptr=0;
  52.         return(p+1);
  53.     }
  54.     if((prevp=_freep)==0){   /*  noch keine base */
  55.         _base.s.ptr=_freep=prevp=&_base;
  56.         _base.s.size=0;
  57.     }
  58.     for(p=prevp->s.ptr;;prevp=p,p=p->s.ptr){
  59.         if(p->s.size>=nunits){  /*  Block passt */
  60.             if(p->s.size==nunits){  /*  genau   */
  61.                 prevp->s.ptr=p->s.ptr;
  62.             }else{  /*  ist kleiner */
  63.                 p->s.size-=nunits;p+=p->s.size;p->s.size=nunits;
  64.             }
  65.             _freep=prevp;
  66.             return((void *)(p+1));
  67.         }
  68.         /*  mehr Speicher anfordern     */
  69.         if(p==_freep) if(!(p=_morecore(nunits))) return(0);
  70.     }
  71. }
  72. void free(void *ap)
  73. {
  74.     union _mheader *bp,*p,*last;
  75.     bp=(union _mheader *)ap;
  76.     if(!bp) return;
  77.     bp--;
  78.     if(bp->s.size>_nalloc){
  79.     /*  grosse Bloecke gleich freigeben     */
  80.         bp--;   /*  Startadresse der mlist  */
  81.         p=_first_mlist;
  82. /*        printf("bp=%p\n",bp);*/
  83.         while(p){
  84. /*            printf("p=%p\n",p);*/
  85.             if(p==bp){  /*  Block gefunden  */
  86.                 if(p==_first_mlist) _first_mlist=p->s.ptr;
  87.                     else last->s.ptr=p->s.ptr;
  88.                 if(p==_last_mlist) _last_mlist=last;
  89.                 FreeMem(p,p->s.size*sizeof(union _mheader));
  90.                 return;
  91.             }
  92.             last=p;p=p->s.ptr;
  93.         }
  94.         /*  wenn man hierherkommt, koennte man einen Fehler melden  */
  95.         Write(Output(),"memory list corrupt!\n",21);
  96.         return;
  97.     }
  98.     for(p=_freep;!(bp>p&&bp<p->s.ptr);p=p->s.ptr)
  99.         if(p>=p->s.ptr&&(bp>p||bp<p->s.ptr))
  100.             break;
  101.  
  102.     if(bp+bp->s.size==p->s.ptr){
  103.         bp->s.size+=p->s.ptr->s.size;
  104.         bp->s.ptr=p->s.ptr->s.ptr;
  105.     }else{
  106.         bp->s.ptr=p->s.ptr;
  107.     }
  108.     if(p+p->s.size==bp){
  109.         p->s.size+=bp->s.size;
  110.         p->s.ptr=bp->s.ptr;
  111.     }else{
  112.         p->s.ptr=bp;
  113.     }
  114.     _freep=p;
  115. }
  116.  
  117.