/* * free */ void free (void *ptr) { unsigned oldS;//store original size that ptr points to unsigned neighS;//neighbor size void *nextPtr;//used for forwards just for ease of typing if(!ptr || !in_heap(ptr)) return; ptr--; setAlloc(ptr, 0); setAlloc(ptr+(block_size(ptr)+1), 0); /* Coalesce Backwards: */ if(!is_alloc((ptr-1))){ oldS=block_size(ptr); neighS=block_size(ptr-1); ptr-=(neighS+2); createBlock(ptr, neighS+oldS+2, 0); } /* Coalesce Forwards: *independent from backwards, just use ptr */ nextPtr=ptr+block_size(ptr)+2; if(!is_alloc(nextPtr)) createBlock(ptr, block_size(nextPtr)+2, 0); }
/* * malloc */ void *malloc (size_t size) { void *currentBlock=start+2; unsigned newSize=(ALIGN(size))<<3;//newSize is number of words (round up) unsigned sizeToAlloc; void *placeToAlloc;//only used if need more space /* Look at all available blocks: */ while(block_size(currentBlock)!=0){ unsigned blockSize=block_size(currentBlock); if((blockSize>=newSize) && is_alloc(currentBlock))//found space return malloc_here(currentBlock, newSize); else //too small currentBlock+=(blockSize+2); } /* No block will fit, add memory, currentBlock points to null block at end */ sizeToAlloc=max(START_SIZE, newSize+2); if(!mem_sbrk(sizeToAlloc)) return NULL; totalSize+=sizeToAlloc; placeToAlloc=currentBlock; /* set new block informatoin: */ currentBlock=createBlock(currentBlock, (sizeToAlloc-2), 0); createBlock(currentBlock, 0, 1); return malloc_here(placeToAlloc, newSize); }
kern_return_t ipc_space_create( ipc_table_size_t initial, ipc_space_t *spacep) { ipc_space_t space; ipc_entry_t table; ipc_entry_num_t new_size; mach_port_index_t index; space = is_alloc(); if (space == IS_NULL) return KERN_RESOURCE_SHORTAGE; table = it_entries_alloc(initial); if (table == IE_NULL) { is_free(space); return KERN_RESOURCE_SHORTAGE; } new_size = initial->its_size; memset((void *) table, 0, new_size * sizeof(struct ipc_entry)); /* * Initialize the free list in the table. * Add the entries in reverse order, and * set the generation number to -1, so that * initial allocations produce "natural" names. */ for (index = 0; index < new_size; index++) { ipc_entry_t entry = &table[index]; entry->ie_bits = IE_BITS_GEN_MASK; entry->ie_next = index+1; } table[new_size-1].ie_next = 0; is_ref_lock_init(space); space->is_references = 2; is_lock_init(space); space->is_active = TRUE; space->is_growing = FALSE; space->is_table = table; space->is_table_size = new_size; space->is_table_next = initial+1; ipc_splay_tree_init(&space->is_tree); space->is_tree_total = 0; space->is_tree_small = 0; space->is_tree_hash = 0; *spacep = space; return KERN_SUCCESS; }
/* * Initialize: return -1 on error, 0 on success. */ int mm_init(void) { start=mem_sbrk(START_SIZE); if(!start) return -1; totalSize=START_SIZE; //initialize begining block void *temp=createBlock(start, 0, 1); *((unsigned *)start)=(0<<1)|(1); printf("\n\nStart: %d => %d, %d\n", *(unsigned *)start, block_size(start), is_alloc(start)); printf("SIZES: u: %lu, i: %lu\n, l:%lu", sizeof(unsigned), sizeof(int), sizeof(long int)); //initialize middle block temp=createBlock(temp, (START_SIZE-6), 0); //initialize ending block createBlock(temp, 0, 1); printf("\n\nBAD: %d, %d, 1? %d\n", block_size(start), is_alloc(start), (*((unsigned *)start)==1)); printf("Big block: %d, %d\n", block_size(start+2), is_alloc(start+2)); return 0; }
kern_return_t ipc_space_create_special( ipc_space_t *spacep) { ipc_space_t space; space = is_alloc(); if (space == IS_NULL) return KERN_RESOURCE_SHORTAGE; is_ref_lock_init(space); space->is_references = 1; is_lock_init(space); space->is_active = FALSE; *spacep = space; return KERN_SUCCESS; }
kern_return_t ipc_space_create_special( ipc_space_t *spacep) { ipc_space_t space; space = is_alloc(); if (space == IS_NULL) return KERN_RESOURCE_SHORTAGE; is_lock_init(space); space->is_bits = IS_INACTIVE | 1; /* 1 ref, not active, not growing */ space->is_table = IE_NULL; space->is_task = TASK_NULL; space->is_table_next = 0; space->is_low_mod = 0; space->is_high_mod = 0; *spacep = space; return KERN_SUCCESS; }
void setBlock(void *p, unsigned s){ setHeader(p, s, is_alloc(p)); }
/* * mm_checkheap */ void mm_checkheap(int verbose) { void *currentBlock=start; printf("\nChecking Heap: verbose=%d\n", verbose); if(verbose==1){ setHeader(currentBlock, 42,0); if(is_alloc(currentBlock)) printf("ERROR: is_alloc didn't work\n"); if(block_size(currentBlock)!=42) printf("ERROR: block_size didn't work\n"); setHeader(currentBlock, 0, 1); if((block_size(currentBlock)!=0) || (!is_alloc(currentBlock))) printf("ERROR: is_alloc, block_size, or setHeader didn't work \n"); printf("Tested setting and reading header\n"); }//only test to see if reading size and alloc and setHeader works if(verbose>=2){ if((*((unsigned *)currentBlock))!=1) printf("ERROR: Bad dummy starter header: %d => %d, %d\n", (*(unsigned *)currentBlock), block_size(currentBlock), is_alloc(currentBlock)); currentBlock++; if((*((unsigned *)currentBlock))!=1) printf("ERROR: Bad dummy starter footer: %d => %d, %d\n", (*(unsigned *)currentBlock), block_size(currentBlock), is_alloc(currentBlock)); } if(verbose>=3){ while(block_size(currentBlock)!=0){ if(!in_heap(currentBlock)) printf("ERROR: Out of heap\n"); if(!aligned(currentBlock)) printf("ERROR: Not aligned\n"); /* header and footer information is the same */ if((*((unsigned *)currentBlock))!= (*((unsigned *)(currentBlock+block_size(currentBlock)+1)))) printf("ERROR: Header and Footer don't match up\n"); /* if current block is not allocated make sure the next one is * only check inforward direction because every block checks */ if(!(is_alloc(currentBlock) || is_alloc(currentBlock+block_size(currentBlock)+2))) printf("ERROR: coalescing fail\n"); }//check all middle blocks } else currentBlock=start+totalSize-2; if(verbose>=2){ if((*(unsigned *)currentBlock)!=1) printf("ERROR: Bad dummy finisher header: %d, %d\n", block_size(currentBlock), is_alloc(currentBlock)); currentBlock++; if((*(unsigned *)currentBlock)!=1) printf("ERROR: Bad dummy finisher footer: %d, %d\n", block_size(currentBlock), is_alloc(currentBlock)); if(mem_heap_hi()!=currentBlock) printf("ERROR: final block isn't heap high\n"); } printf("Finished checking heap\n"); }