home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
-
- /*#include <exec/memory.h>*/
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- /* stark modifizierte Version aus K&R */
-
- static union _mheader _base;
- static union _mheader *_freep=0;
-
- size_t _nalloc=1023;
- union _mheader *_first_mlist=0,*_last_mlist=0;
-
- union _mheader *_morecore(size_t anu)
- {
- union _mheader *up;size_t nu;
- if(anu<_nalloc) nu=_nalloc; else nu=anu;
- up=(union _mheader *)AllocMem((nu+1)*sizeof(union _mheader),0L);
- if(!up) return(0);
- up->s.size=nu+1; up->s.ptr=0; /* Merken fuer Freigabe am Schluss */
- if(_last_mlist){
- _last_mlist->s.ptr=up;_last_mlist=up;
- }else{
- _last_mlist=_first_mlist=up;
- }
- up++;
- up->s.size=nu;
- if(anu>_nalloc) return((void *)up);
- free((void *)(up+1));
- return(_freep);
- }
- void _freemem(void)
- /* Gibt allen Speicher frei */
- {
- union _mheader *p=_first_mlist,*m;
- while(p){
- m=p->s.ptr;
- FreeMem(p,p->s.size*sizeof(union _mheader));
- p=m;
- }
- }
- void *malloc(size_t nbytes)
- {
- union _mheader *p,*prevp;
- size_t nunits;
- /* aufrunden */
- nunits=(nbytes+sizeof(union _mheader)-1)/sizeof(union _mheader)+1;
- if(nunits>_nalloc){
- if(!(p=_morecore(nunits))) return(0);
- p->s.size=nunits;p->s.ptr=0;
- return(p+1);
- }
- if((prevp=_freep)==0){ /* noch keine base */
- _base.s.ptr=_freep=prevp=&_base;
- _base.s.size=0;
- }
- for(p=prevp->s.ptr;;prevp=p,p=p->s.ptr){
- if(p->s.size>=nunits){ /* Block passt */
- if(p->s.size==nunits){ /* genau */
- prevp->s.ptr=p->s.ptr;
- }else{ /* ist kleiner */
- p->s.size-=nunits;p+=p->s.size;p->s.size=nunits;
- }
- _freep=prevp;
- return((void *)(p+1));
- }
- /* mehr Speicher anfordern */
- if(p==_freep) if(!(p=_morecore(nunits))) return(0);
- }
- }
- void free(void *ap)
- {
- union _mheader *bp,*p,*last;
- bp=(union _mheader *)ap;
- if(!bp) return;
- bp--;
- if(bp->s.size>_nalloc){
- /* grosse Bloecke gleich freigeben */
- bp--; /* Startadresse der mlist */
- p=_first_mlist;
- /* printf("bp=%p\n",bp);*/
- while(p){
- /* printf("p=%p\n",p);*/
- if(p==bp){ /* Block gefunden */
- if(p==_first_mlist) _first_mlist=p->s.ptr;
- else last->s.ptr=p->s.ptr;
- if(p==_last_mlist) _last_mlist=last;
- FreeMem(p,p->s.size*sizeof(union _mheader));
- return;
- }
- last=p;p=p->s.ptr;
- }
- /* wenn man hierherkommt, koennte man einen Fehler melden */
- Write(Output(),"memory list corrupt!\n",21);
- return;
- }
- for(p=_freep;!(bp>p&&bp<p->s.ptr);p=p->s.ptr)
- if(p>=p->s.ptr&&(bp>p||bp<p->s.ptr))
- break;
-
- if(bp+bp->s.size==p->s.ptr){
- bp->s.size+=p->s.ptr->s.size;
- bp->s.ptr=p->s.ptr->s.ptr;
- }else{
- bp->s.ptr=p->s.ptr;
- }
- if(p+p->s.size==bp){
- p->s.size+=bp->s.size;
- p->s.ptr=bp->s.ptr;
- }else{
- p->s.ptr=bp;
- }
- _freep=p;
- }
-
-