#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&&addrprintf("Freeing 32 byte ob\n"); } else if(addr>=heap_128&&addrprintf("Freeing 128 byte ob\n"); free_128(addr); } else if(addr>=heap_256&&addrprintf("Freeing 256 byte ob\n"); free_256(addr); //} else if(addr>=heap_512&&addrprintf("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_128) PANIC("BAD FREE"); debug con->printf("free32: addr=%X\thead=%X\n",addr,head32); if(head32) if((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_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+heap_len) PANIC("Head32 is not legal."); void*ret=head32; head32=(void*)*h; return ret; }