All pastes #1532482 Raw Edit

richard

public text v1 · immutable
#1532482 ·published 2009-08-17 12:49 UTC
rendered paste body
#ifndef _HEAP_H#define _HEAP_H#include "types.h"class KernelSlabAllocator {	public:	KernelSlabAllocator();	void *alloc(u32 size);	void free(void* ob);private:	void get_more_256();	void get_more_128();	void get_more_32();	void free_32(u32 addr);	void free_128(u32 addr);	void free_256(u32 addr);	void*alloc_256();	void*alloc_128();	void*alloc_32();	u32 heap_32;	u32 heap_128;	u32 heap_256;	u32 heap_512;	u32 heap_len;	u32 pages32,pages128,pages256,pages512;	void *head32,*head128,*head256,*head512;};extern KernelSlabAllocator slab;void* operator new(u32 size);void operator delete (void *p);#endif#include "heap.h"#include "vm2.h"void* operator new(u32 size){	return slab.alloc(size);}void operator delete (void *p) {	slab.free(p);}#include "terminal.h"KernelSlabAllocator slab;extern AddressSpace kernel_address_space;static bool DEBUGMM=false;#define debug if(DEBUGMM)KernelSlabAllocator::KernelSlabAllocator() {	AddressSpace &addr=kernel_address_space;	heap_32= 0xc0800000;	heap_128=0xc1000000;	heap_256=0xc1800000;	heap_512=0xc2000000;	heap_len=0x00400000;	head32=head128=head256=head512=0;	addr.ensure_page_table(heap_32,0);	addr.ensure_page_table(heap_128,0);	addr.ensure_page_table(heap_256,0);	addr.ensure_page_table(heap_512,0);}void* KernelSlabAllocator::alloc(u32 size) {	if(size<32) {		debug con->printf("Allocating %d bytes for a %d byte object.\n",32,size);		void* p=alloc_32();		debug con->printf("Got %X\n",p);		return p;	} else if(size<128) {		debug con->printf("Allocating %d bytes for a %d byte object.\n",128,size);		return alloc_128();	} else if(size<256) {		debug con->printf("Allocating %d bytes for a %d byte object.\n",256,size);		return alloc_256();	} else {		con->printf("Requested size (%d bytes) not servicable\n",size);		PANIC("NO SUPPORT FOR THIS SIZE!");		return 0;	}}void KernelSlabAllocator::free(void* ob) {	u32 addr=(u32)ob;	if(addr>=heap_32&&addr<heap_32+heap_len) {		free_32(addr);		debug con->printf("Freeing 32 byte ob\n");	} else if(addr>=heap_128&&addr<heap_128+heap_len) {		debug con->printf("Freeing 128 byte ob\n");		free_128(addr);	} else if(addr>=heap_256&&addr<heap_256+heap_len) {		debug con->printf("Freeing 256 byte ob\n");		free_256(addr);	//} else if(addr>=heap_512&&addr<heap_512+heap_len) {	} else {		con->printf("failed to free %X\n",ob);		PANIC("INVALID FREE (doesn't fit any of the buckets\n");	}}void KernelSlabAllocator::get_more_256() {	if(pages256>=1024)		PANIC("can't allocate any more space for 128 byte bits...\n");	u32 start_addr=((pages256<<12) + heap_256);	u32 end_addr=start_addr+0x1000;	kernel_address_space.map_anon(start_addr,0,1);	for(u32 it=start_addr;it!=end_addr;it+=256) {		free_256(it);	}	++pages256;}void KernelSlabAllocator::get_more_128() {	if(pages128>=1024)		PANIC("can't allocate any more space for 128 byte bits...\n");	u32 start_addr=((pages128<<12) + heap_128);	u32 end_addr=start_addr+0x1000;	kernel_address_space.map_anon(start_addr,0,1);	for(u32 it=start_addr;it!=end_addr;it+=128) {		free_128(it);	}	++pages128;}void KernelSlabAllocator::get_more_32() {	if(pages32>=1024)		PANIC("can't allocate any more space for 128 byte bits...\n");	u32 start_addr=((pages32<<12) + heap_32);	debug con->printf("Allocating another page for the 32 bit heap: %X\n",start_addr);	u32 end_addr=start_addr+0x1000;	kernel_address_space.map_anon(start_addr,0,1);	for(u32 it=start_addr;it!=end_addr;it+=32) {		free_32(it);	}	++pages32;}void KernelSlabAllocator::free_32(u32 addr) {	if(addr<heap_32||addr>=heap_128)		PANIC("BAD FREE");	debug con->printf("free32: addr=%X\thead=%X\n",addr,head32);	if(head32)	if((u32)head32<heap_32||(u32)head32>=heap_32+heap_len)		PANIC("The heap32 head got changed underneath us...");	u32* p=(u32*)(addr);	*p=(u32)head32;	head32=(void*)addr;}void KernelSlabAllocator::free_128(u32 addr) {	u32* p=(u32*)(addr);	*p=(u32)head128;	head128=(void*)p;}void KernelSlabAllocator::free_256(u32 addr) {	if(addr<heap_256||addr>=heap_512)		PANIC("BAD FREE");	u32* p=(u32*)(addr);	*p=(u32)head256;	debug con->printf("free256: addr=%X\thead=%X\n",addr,head256);	head256=(void*)p;}void* KernelSlabAllocator::alloc_256() {	if(!head256)		get_more_256();	u32 *h=(u32*)head256;	void*ret=head256;	head256=(void*)*h;	return ret;}void* KernelSlabAllocator::alloc_128() {	if(!head128)		get_more_128();	u32 *h=(u32*)head128;	void*ret=head128;	head128=(void*)*h;	return ret;}void* KernelSlabAllocator::alloc_32() {	if(!head32) {		debug con->printf("Had to make another page for heap32\n");		get_more_32();	}	u32 *h=(u32*)head32;	debug con->printf("head32=%X\n",head32);	if((u32)head32<heap_32||(u32)head32>=heap_32+heap_len)		PANIC("Head32 is not legal.");	void*ret=head32;	head32=(void*)*h;	return ret;}