void KHeap::install(uint32_t start, const uint32_t &end, const uint32_t &max, const bool &supervisor, const bool &readonly) { index=new Ordered_array<header_t*>( (void*)(start), KHEAP_INDEX_SIZE ); //// index=(Ordered_array<header_t*>*)( kmalloc( sizeof(index) ) ); //// index->init( (void*)(start), KHEAP_INDEX_SIZE ); // heap_t *heap = (heap_t*)( kmalloc(sizeof(heap_t)) ); // All our assumptions are made on startAddress and endAddress being page-aligned. ASSERT(start%0x1000 == 0); ASSERT(end_address()%0x1000 == 0); // Initialise the index. // heap->index = place_ordered_array( (void*)start, HEAP_INDEX_SIZE, &header_t_less_than); // Shift the start address forward to resemble where we can start putting data. // start += sizeof(type_t)*HEAP_INDEX_SIZE; start += index->abs_size(); // Make sure the start address is page-aligned. if( (start&0xFFFFF000)!=0 ) { start &= 0xFFFFF000; start += 0x1000; } // Write the start, end and max addresses into the heap structure. start_address(start); end_address(end); max_address(max); this->supervisor(supervisor); this->readonly(readonly); // We start off with one large hole in the index. header_t *hole=(header_t *)(start); hole->size=end_address()-start_address(); hole->magic=KHEAP_MAGIC; hole->is_hole=true; /* kprintf("FREEEEEEEE!!! header->magic=%p\n",hole->magic); kprintf("FREEEEEEEE! header->size=%u\n",hole->size); kprintf("FREEEEEEEE! header=%p\n",hole); */ index->insert(hole); kheap_kfree_handler=this; kfree_set_handler(kheap_kfree); kheap_kmalloc_handler=this; kmalloc_set_handler(kheap_kmalloc); paging.current_directory=paging.clone_directory(paging.kernel_directory); paging.switch_page_directory(paging.current_directory); // kprintf("Sai!!!\n"); // halt_machine(); }
uint32_t KHeap::contract(uint32_t new_size) { // Sanity check. ASSERT( new_size<end_address()-start_address()); // Get the nearest following page boundary. if( new_size&0x1000 ) { new_size&=0x1000; new_size+=0x1000; } // Don't contract too far! if( new_size<KHEAP_MIN_SIZE ) { new_size = KHEAP_MIN_SIZE; } uint32_t old_size=end_address()-start_address(); uint32_t i=old_size-0x1000; while( new_size<i ) { paging.free_frame( paging.get_page(start_address()+i, false, paging.kernel_directory) ); i -= 0x1000; } end_address( start_address()+new_size ); return new_size; }
void KHeap::expand( uint32_t new_size ) { // Sanity check. ASSERT(new_size>end_address()-start_address()); // Get the nearest following page boundary. if( (new_size&0xFFFFF000)!=0 ) { new_size &= 0xFFFFF000; new_size += 0x1000; } // Make sure we are not overreaching ourselves. ASSERT( start_address()+new_size<=max_address()); // This should always be on a page boundary. uint32_t old_size=end_address()-start_address(); uint32_t i=old_size; while( i<new_size ) { paging.alloc_frame( paging.get_page(start_address()+i, true, paging.kernel_directory), supervisor(), !readonly() ); i += 0x1000 /* page size */; } end_address( start_address()+new_size ); }
int main(int argc, const char * argv[]) { vector < Passenger > passengersA; vector < Passenger > passengersB; passengersB.push_back(Passenger("Saffron",200,50 ,Coordinate(20,15,12,"Delphi System"),"I travel very light")); passengersB.push_back(Passenger("Mrs. Reynolds",150,120 ,Coordinate(2,2,2,"Europa Colony"),"Just trying to get back my husband!")); passengersB.push_back(Passenger("Yolanda",500,100 ,Coordinate(20,15,12,"Delphi System"),"I am a courier of sensitive items")); passengersB.push_back(Passenger("Tracey Smith ",200,50 ,Coordinate(20,15,12,"Delphi System"),"Just a guy")); passengersA.push_back(Passenger("Magistrate Higgins ",600,120 ,Coordinate(2,2,2,"Europa Colony"),"I am very important person")); passengersA.push_back(Passenger("Stitch Hessian",100,100 ,Coordinate(100,72,32,"3rd moon of Persephone"),"Just get me there")); Coordinate earth(0,0,0,"Earth"); Coordinate europa(2,2,2,"Europa Colony"); vector< CargoBin > cargo; cargo.push_back(*new CargoBin(ACR.WARP,10)); cargo.push_back(*new CargoBin(ACR.ISOLC,10)); vector< SpaceThing > stations; stations.push_back( *new SpaceThing("Far Point Station",100,100,cargo,europa,passengersB) ); stations.push_back( *new SpaceThing("Mars Research Station",100,100,cargo,europa,passengersB) ); stations.push_back( *new SpaceThing("Earth Space Command Station",100,100,cargo,europa,passengersB) ); //=====================================everything above line is dummy data, replace with an object factory //SpaceFactory factory = SpaceFactory("/Users/Neil/Dropbox/webster/COSC4260/IAWSCA/SpaceFactory/"); //vector< SpaceThing > stations(randomStations(5)); //Dosn't work. Don't know why. Memory error in buy. Can't hunt it down. Brain is fried, out of time. Ship ship(interface,"HMS Out Of Time",1000,2000,cargo,earth,passengersA); bool close; string choices[] = {//TODO: map menu options to function pointers?? "TRADE CARGO", //1 "LOAD PASSENGERS", //2 "SET COURSE", //3 "DOCK", //4 "MANAGE CARGO", //5 "VIEW PASSENGERS", //6 }; interface.message("Welcome to your space ship",true); vector < string > mainMenu(begin_address(choices),end_address(choices)); while (!close) { ship.displayHUD(); int choice = interface.showMenu("\n\nMAIN MENU", mainMenu,"Please choose an action"); switch (choice){ case 1: ship.buy(); break; case 2: ship.loadPassengers(); break; case 3: ship.setNewCourse(); break; case 4: ship.dock(stations); //stations = randomStations(5); break; case 5: ship.manageInventory(); break; case 6: ship.viewPassengers(); break; case 7: close = interface.prompt("Are you sure you want to quit","Yes","No"); break; } } quit(); return 0; }
void *KHeap::alloc(uint32_t size, const bool &page_align) { // Make sure we take the size of header/footer into account. uint32_t new_size = size + sizeof(header_t) + sizeof(footer_t); // Find the smallest hole that will fit. uint32_t iterator = find_smallest_hole(new_size, page_align); if( iterator==(uint32_t)(-1) ) { // If we didn't find a suitable hole // Save some previous data. uint32_t old_length=end_address()-start_address(); uint32_t old_end_address=end_address(); // We need to allocate some more space. expand(old_length+new_size); uint32_t new_length=end_address()-start_address(); // Find the endmost header. (Not endmost in size, but in location). iterator=0; // Vars to hold the index of, and value of, the endmost header found so far. uint32_t idx=-1; uint32_t value = 0x0; while( iterator<index->size() ) { uint32_t tmp=(uint32_t)( (*index)[iterator] ); if( tmp>value ) { value=tmp; idx=iterator; } ++iterator; } // If we didn't find ANY headers, we need to add one. if( idx==(uint32_t)(-1) ) { header_t *header=(header_t*)(old_end_address); header->magic=KHEAP_MAGIC; header->size=new_length-old_length; header->is_hole=true; footer_t *footer=(footer_t *)(old_end_address+header->size-sizeof(footer_t)); footer->magic=KHEAP_MAGIC; footer->header=header; /* kprintf("FREEEEEEEE! header->magic=%p\n",header->magic); kprintf("FREEEEEEEE! header->size=%u\n",header->size); kprintf("FREEEEEEEE! header=%p\n",header);*/ index->insert( header ); } else { // The last header needs adjusting. header_t *header=(*index)[idx]; header->size+=new_length-old_length; // Rewrite the footer. footer_t *footer=(footer_t*)( (uint32_t)header+header->size-sizeof(footer_t) ); footer->header=header; footer->magic=KHEAP_MAGIC; } // We now have enough space. Recurse, and call the function again. return alloc(size, page_align); } header_t *orig_hole_header=(*index)[iterator]; uint32_t orig_hole_pos=(uint32_t)orig_hole_header; uint32_t orig_hole_size=orig_hole_header->size; // Here we work out if we should split the hole we found into two parts. // Is the original hole size - requested hole size less than the overhead for adding a new hole? if( orig_hole_size-new_size<sizeof(header_t)+sizeof(footer_t) ) { // Then just increase the requested size to the size of the hole we found. size += orig_hole_size-new_size; new_size = orig_hole_size; } // If we need to page-align the data, do it now and make a new hole in front of our block. if( page_align && orig_hole_pos&0xFFFFF000 ) { uint32_t new_location = orig_hole_pos+0x1000 /* page size */ - (orig_hole_pos&0xFFF) - sizeof(header_t); header_t *hole_header = (header_t *)orig_hole_pos; hole_header->size = 0x1000 /* page size */ - (orig_hole_pos&0xFFF) - sizeof(header_t); hole_header->magic = KHEAP_MAGIC; hole_header->is_hole = 1; footer_t *hole_footer = (footer_t *) ( (uint32_t)new_location - sizeof(footer_t) ); hole_footer->magic = KHEAP_MAGIC; hole_footer->header = hole_header; orig_hole_pos = new_location; orig_hole_size = orig_hole_size - hole_header->size; } else { // Else we don't need this hole any more, delete it from the index. index->remove(iterator); } // Overwrite the original header... header_t *block_header = (header_t*)orig_hole_pos; block_header->magic = KHEAP_MAGIC; block_header->is_hole = 0; block_header->size = new_size; // ...And the footer footer_t *block_footer = (footer_t *) (orig_hole_pos + sizeof(header_t) + size); block_footer->magic = KHEAP_MAGIC; block_footer->header = block_header; // We may need to write a new hole after the allocated block. // We do this only if the new hole would have positive size... if( orig_hole_size-new_size>0 ) { header_t *hole_header = (header_t *) (orig_hole_pos + sizeof(header_t) + size + sizeof(footer_t)); hole_header->magic = KHEAP_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; footer_t *hole_footer = (footer_t *) ( (uint32_t)hole_header + orig_hole_size - new_size - sizeof(footer_t) ); if( (uint32_t)hole_footer<end_address() ) { hole_footer->magic = KHEAP_MAGIC; hole_footer->header = hole_header; } // Put the new hole in the index; /* kprintf("FREEEEEEEE! header->magic=%p\n",hole_header->magic); kprintf("FREEEEEEEE! header->size=%u\n",hole_header->size); kprintf("FREEEEEEEE! header=%p\n",hole_header);*/ index->insert(hole_header); } // ...And we're done! return (void*)( (uint32_t)block_header+sizeof(header_t) ); }