void sal_merge(vaddr_t objectHeader) { free_header_t *currNode = (free_header_t *) &memory[objectHeader]; free_header_t *prevNode = (free_header_t *) &memory[currNode->prev]; free_header_t *nextNode = (free_header_t *) &memory[currNode->next]; int merged = FALSE; vaddr_t nextMergeHeader = objectHeader; //printf("Curr beside next %d %d %d \n", objectHeader, currNode->prev + prevNode->size, currNode->next); //printf("curr beside prev %p %p\n",) //printf("objectHeader is %d\n", objectHeader % (2*currNode->size)); //printf("free_list_ptr is %d\n", free_list_ptr); if (objectHeader % (2*currNode->size) == 0){ if ((currNode->size == nextNode->size) && (objectHeader + currNode->size == currNode->next)) { if (nextNode->next == currNode->next) { currNode->size = 2*currNode->size; currNode->next = objectHeader; currNode->prev = objectHeader; free_list_ptr = objectHeader; } else { currNode->next = nextNode->next; currNode->size = 2*currNode->size; free_header_t *newNextNode = (free_header_t *) &memory[nextNode->next]; newNextNode->prev = objectHeader; } merged = TRUE; } else { //printf("No more merging to be done\n"); } } else if ((currNode->size == prevNode->size) && (currNode->prev + prevNode->size == objectHeader)) { // or use index of prevNode and currNode prevNode->next = currNode->next; prevNode->size = 2*prevNode->size; free_header_t *newNextNode = (free_header_t *) &memory[currNode->next]; if(currNode->size >= memory_size/2) { newNextNode->prev = 0; } else { newNextNode->prev = objectHeader - prevNode->size; } merged = TRUE; nextMergeHeader = currNode->prev; } else{ // printf("No more merging to be done - not on size interval\n"); } // If a merge done, call sal_merge again if(merged == TRUE) { sal_merge(nextMergeHeader); } }
void sal_free(void *object) { long index = (long) object - HEADER_SIZE; long prevInd=-1; long merged=0; //unchanged if no merging occurs free_header_t *curr = (free_header_t *)(memory + index); if (curr->magic==MAGIC_ALLOC){ prevInd = scanForLow(index); //scan for lowest curr->magic = MAGIC_FREE; //if merging node is 1st in list, link accordingly (next 7 lines) if (prevInd==-1){ free_header_t *nex = (free_header_t *)(memory + free_list_ptr); curr->prev = nex->prev; nex->prev = index; curr->next = (long) nex - (long) memory; nex = (free_header_t *)(memory + curr->prev); nex->next = index; free_list_ptr = index; } else { //if not 1st, link accordingly (next 6 lines); curr->prev = prevInd; free_header_t *before = (free_header_t *) (memory + prevInd); curr->next = before->next; before->next = index; before = (free_header_t *) (memory + curr->next); before->prev = index; } while (merged!=-1){ //while a merging occured merged = sal_merge(index); //attempt to merge index header if (merged!=-1 && merged!=1) { index = merged; //if merged below, change index } } //if not alloc'd memory, send error message } else { fprintf(stderr, "Attempt to free non-allocated memory"); abort(); } }
void sal_free(void *object) { object -= 256; if(object < (void *) memory || object > (void *) (memory+memory_size)) { // Pointer given is not inside our memory block fprintf(stderr, "sal_free: non-valid pointer given\n"); abort(); } //printf("Object at address %p\n", object); vaddr_t currNodeIndex = object - (void *) memory; //printf("currNodeIndex is %d\n", currNodeIndex); //printf("currNodeIndex is %lu\n", currNodeIndex - HEADER_SIZE); //printf("currNodeIndex at address %p\n", &memory[currNodeIndex]); free_header_t *currNode = (free_header_t*) &memory[currNodeIndex]; /*if (currNodeIndex < 0 || currNodeIndex > memory_size) { // Pointer given is not inside our memory block fprintf(stderr, "sal_free: non-valid pointer given\n"); abort(); }*/ if (currNode->magic != MAGIC_ALLOC) { // Given pointer doesn't point to a "valid" and allocated memory fprintf(stderr, "Attempt to free non-allocated memory"); abort(); } /* // Take a reference to the first and last node in free-list vaddr_t firstNodeIndex = free_list_ptr; free_header_t *firstNode = (free_header_t*) &memory[firstNodeIndex]; vaddr_t lastNodeIndex = firstNode->prev; free_header_t *lastNode = (free_header_t*) &memory[lastNodeIndex]; // Make currNode's next = firstNode, and prev = lastNode; currNode->prev = lastNodeIndex; currNode->next = firstNodeIndex; // Put the currNode between the firstNode and lastNode firstNode->prev = currNodeIndex; lastNode->next = currNodeIndex; */ free_header_t *testNode = (free_header_t *) &memory[free_list_ptr]; if(free_list_ptr > currNodeIndex) { // Set up current node currNode->next = free_list_ptr; currNode->prev = testNode->prev; // Insert free_header_t *lastFreeNode = (free_header_t *) &memory[testNode->prev]; (lastFreeNode)->next = currNodeIndex; testNode->prev = currNodeIndex; // Update free list pointer free_list_ptr = currNodeIndex; } else if(testNode->prev < currNodeIndex){ currNode->next = free_list_ptr; currNode->prev = testNode->prev; // Insert free_header_t *lastFreeNode = (free_header_t *) &memory[testNode->prev]; (lastFreeNode)->next = currNodeIndex; testNode->prev = currNodeIndex; } else { while(TRUE) { if(testNode->next > currNodeIndex) { //insert currNode->prev = (byte *) testNode - memory; currNode->next = testNode->next; free_header_t *nextFreeNode = (free_header_t *) &memory[testNode->next]; (nextFreeNode)->prev = currNodeIndex; testNode->next = currNodeIndex; break; } testNode = (free_header_t *) &memory[testNode->next]; } } // Turn currNode->magic to MAGIC_FREE currNode->magic = MAGIC_FREE; sal_merge(currNodeIndex); }