forsyth20121205-174063a80cc13 years agoHistory
106 lines · 1.7 KB · C
RawDownload
#include "u.h"#include "lib.h"#include "mem.h"#include "dat.h"#include "fns.h" voidmapinit(RMap *rmap, Map *map, int size){	lock(rmap);	rmap->map = map;	rmap->mapend = map+(size/sizeof(Map));	unlock(rmap);} voidmapfree(RMap* rmap, ulong addr, int size){	Map *mp;	ulong t; 	if(size <= 0)		return; 	lock(rmap);	for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)		; 	if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){		(mp-1)->size += size;		if(addr+size == mp->addr){			(mp-1)->size += mp->size;			while(mp->size){				mp++;				(mp-1)->addr = mp->addr;				(mp-1)->size = mp->size;			}		}	}	else{		if(addr+size == mp->addr && mp->size){			mp->addr -= size;			mp->size += size;		}		else do{			if(mp >= rmap->mapend){				print("mapfree: %s: losing 0x%luX, %d\n",					rmap->name, addr, size);				break;			}			t = mp->addr;			mp->addr = addr;			addr = t;			t = mp->size;			mp->size = size;			mp++;		}while(size = t);	}	unlock(rmap);} ulongrmapalloc(RMap* rmap, ulong addr, int size, int align){	Map *mp;	ulong maddr, oaddr; 	lock(rmap);	for(mp = rmap->map; mp->size; mp++){		maddr = mp->addr; 		if(addr){			if(maddr > addr)				break;			if(maddr+mp->size < addr)				continue;			if(addr+size > maddr+mp->size)				break;			maddr = addr;		} 		if(align > 0)			maddr = ((maddr+align-1)/align)*align;		if(mp->addr+mp->size-maddr < size)			continue; 		oaddr = mp->addr;		mp->addr = maddr+size;		mp->size -= maddr-oaddr+size;		if(mp->size == 0){			do{				mp++;				(mp-1)->addr = mp->addr;			}while((mp-1)->size = mp->size);		} 		unlock(rmap);		if(oaddr != maddr)			mapfree(rmap, oaddr, maddr-oaddr); 		return maddr;	}	unlock(rmap); 	return 0;}