Commit c22d29cf authored by Paras Garg's avatar Paras Garg

final version

parent 46391aa2
......@@ -437,7 +437,7 @@ static void remove_range(range_t **ranges, char *lo)
range_t **prevpp = ranges;
int size;
for (p = *ranges; p != NULL; p = p->next) {
for (p = *ranges; p != NULL; p = p->next) {
if (p->lo == lo) {
*prevpp = p->next;
size = p->hi - p->lo + 1;
......
/*
* mm-naive.c - The fastest, least memory-efficient malloc package.
*
* In this naive approach, a block is allocated by simply incrementing
* the brk pointer. A block is pure payload. There are no headers or
* footers. Blocks are never coalesced or reused. Realloc is
* implemented directly using mm_malloc and mm_free.
*
* NOTE TO STUDENTS: Replace this header comment with your own header
* comment that gives a high level description of your solution.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include "mm.h"
#include "memlib.h"
/*********************************************************
* NOTE TO STUDENTS: Before you do anything else, please
* provide your team information in the following struct.
********************************************************/
team_t team = {
/* Team name */
"team name",
/* First member's full name */
"member 1",
/* First member's email address */
"member_1@cse.iitb.ac.in",
/* Second member's full name (leave blank if none) */
"member 2",
/* Second member's email address (leave blank if none) */
"member_2@cse.iitb.ac.in"
};
/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
/*
* mm_init - initialize the malloc package.
*/
void *init_mem_sbrk_break = NULL;
int mm_init(void)
{
//This function is called every time before each test run of the trace.
//It should reset the entire state of your malloc or the consecutive trace runs will give wrong answer.
/*
* This function should initialize and reset any data structures used to represent the starting state(empty heap)
*
* This function will be called multiple time in the driver code "mdriver.c"
*/
return 0; //Returns 0 on successfull initialization.
}
//---------------------------------------------------------------------------------------------------------------
/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment.
*/
void *mm_malloc(size_t size)
{
/*
* This function should keep track of the allocated memory blocks.
* The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory.
* The previously freed memory blocks should be reused.
* If no appropriate free block is available then the increase the heap size using 'mem_sbrk(size)'.
* Try to keep the heap size as small as possible.
*/
if(size <= 0){ // Invalid request size
return NULL;
}
size = ((size+7)/8)*8; //size alligned to 8 bytes
return mem_sbrk(size); //mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
}
void mm_free(void *ptr)
{
/*
* Searches the previously allocated node for memory block with base address ptr.
*
* It should also perform coalesceing on both ends i.e. if the consecutive memory blocks are
* free(not allocated) then they should be combined into a single block.
*
* It should also keep track of all the free memory blocks.
* If the freed block is at the end of the heap then you can also decrease the heap size
* using 'mem_sbrk(-size)'.
*/
}
/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/
void *mm_realloc(void *ptr, size_t size)
{
size = ((size+7)/8)*8; //8-byte alignement
if(ptr == NULL){ //memory was not previously allocated
return mm_malloc(size);
}
if(size == 0){ //new size is zero
mm_free(ptr);
return NULL;
}
/*
* This function should also copy the content of the previous memory block into the new block.
* You can use 'memcpy()' for this purpose.
*
* The data structures corresponding to free memory blocks and allocated memory
* blocks should also be updated.
*/
mm_free(ptr);
return mem_sbrk(size);
}
......@@ -28,15 +28,15 @@
team_t team = {
/* Team name */
"team",
"Boolean Pundits",
/* First member's full name */
"Paras Garg",
"paras garg",
/* First member's email address */
"parasgarg@cse.iitb.ac.in",
/* Second member's full name (leave blank if none) */
"member 2",
"Ketan kulkarni",
/* Second member's email address (leave blank if none) */
"member_2@cse.iitb.ac.in"
"ketankulkarni@cse.iitb.ac.in"
};
/* single word (4) or double word (8) alignment */
......@@ -68,32 +68,97 @@ typedef struct blk_footer_t {
size_t size;
}blk_footer;
#define METADATA_SIZE (sizeof(blk_footer)+sizeof(blk_header))
int METADATA_SIZE;
free_blk_header *head;
char* MAX_ADDRESS;
char* MIN_ADDRESS;
void *init_mem_sbrk_break = NULL;
/*
* mm_init - initialize the malloc package.
*/
//functions signature
void removeNodeFromFreeList(free_blk_header * bestfit);
void splitNode(free_blk_header *bestfit,int requiredSize);
void bothfree(blk_header* left,blk_header* curr,blk_header* righthead);
void bothNotFree(blk_header *header);
void leftFree(blk_header* left,blk_header* head);
void rightFree(blk_header* right,blk_header* currhead);
void printmem();
void printfreeList();
int mm_init(void)
{
METADATA_SIZE= sizeof(blk_footer)+sizeof(blk_header);
head=NULL;
MIN_ADDRESS=mem_sbrk(0);
//printf("ini%p",(void*)MIN_ADDRESS);
//printf("starting address %p",(void*)MIN_ADDRESS);
MAX_ADDRESS=MIN_ADDRESS;
/*
* IT resest the head of freelist to null
* memlib reset the heap section used resetting head do the work
if(MIN_ADDRESS==NULL)
return 0;
*/
return 0; //Returns 0 on successfull initialization.
return 1; //Returns 0 on successfull initialization.
}
void removeNodeFromFreeList(free_blk_header * bestfit){
if(bestfit->prev==NULL && bestfit->next==NULL){
//printf("\n\n single node case bestfit %p",(void*)bestfit);
head=NULL;
//case b firs node
}else if(bestfit->prev==NULL){
free_blk_header *nextNode=bestfit->next;
head=nextNode;
nextNode->prev=NULL;
//printf("\n\nfirst node %pnew head %p head prev%p head next%p",(void*)bestfit,(void*)head,(void*)head->prev,(void*)head->next);
//case c last node
}else if(bestfit->next==NULL){
free_blk_header *prevNode=bestfit->prev;
prevNode->next=NULL;
//printf("\n\n last node %p prevnode %p",(void*)bestfit,(void*)prevNode);
//case d middle node
}else{
free_blk_header *nextNode=bestfit->next;
free_blk_header *prevNode=bestfit->prev;
nextNode->prev=prevNode;
prevNode->next=nextNode;
//printf("\n\n middle node %p prevnode next %p nextnode prev%p",(void*)bestfit,(void*)prevNode->next,(void*)nextNode->prev);
}
}
void splitNode(free_blk_header *bestfit,int requiredSize){
int remainSize=bestfit->size-requiredSize;
//SET BESTFIT SIZE TO REQUIRED SIZE
free_blk_header *remainBlk=(free_blk_header*)((char*)bestfit+requiredSize);
remainBlk->size=remainSize;
remainBlk->free=1;
blk_footer *remBlkFooter=(blk_footer*)((char*)remainBlk+remainSize-sizeof(blk_footer));
remBlkFooter->size=remainSize;
remBlkFooter->free=1;
if(bestfit->next==NULL && bestfit->prev==NULL){//case single node
remainBlk->next=NULL;
remainBlk->prev=NULL;
head=remainBlk;
}else if(bestfit->next==NULL){//case last node
bestfit->prev->next=remainBlk;
remainBlk->next=NULL;
remainBlk->prev=bestfit->prev;
}else if(bestfit->prev==NULL){//case first node
remainBlk->prev=NULL;
remainBlk->next=bestfit->next;
bestfit->next->prev=remainBlk;
head=remainBlk;
}else{//case middle node
free_blk_header *prev=bestfit->prev;
free_blk_header *next=bestfit->next;
prev->next=remainBlk;
remainBlk->prev=prev;
remainBlk->next=next;
next->prev=remainBlk;
}
}
//---------------------------------------------------------------------------------------------------------------
/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
......@@ -101,6 +166,7 @@ int mm_init(void)
*/
void *mm_malloc(size_t size)
{
//printf("\n malloc %d",size);
/*
* This function should keep track of the allocated memory blocks.
* The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory.
......@@ -114,15 +180,18 @@ void *mm_malloc(size_t size)
}
size=ALIGN(size);
int requiredSize=size+METADATA_SIZE;
/*
*search in free list if block not found besr
*/
free_blk_header *temp=head;
free_blk_header *bestfit=NULL;
//printmem();
//printfreeList();
while(temp!=NULL){
// printf("\n freelist search block address %p size %d",(void*)temp,temp->size);
fflush(stdout);
fflush(stdout);
if(temp->size >= requiredSize){
if(bestfit==NULL){
bestfit=temp;
}
......@@ -133,56 +202,44 @@ void *mm_malloc(size_t size)
temp=temp->next;
}
if(bestfit!=NULL){
//because block size may be greater and hence
requiredSize=bestfit->size;
//printf("\n block mil gaya");
free_blk_header *prev=bestfit->prev;
temp=bestfit->next;
if(prev==NULL){
if(temp==NULL){
head=NULL;
}else{
head=temp;
temp->prev=NULL;
}
}else{
if(temp==NULL){
prev->next=NULL;
}else{
prev->next=temp;
temp->prev=prev;
}
/*
*IF BESTFIT SIZE GREATER THAN REQUIRED SIZE AND MIN BLKSIZE(METADAT+8BYTE) THEN SPLIT THE BLK AND ADJUST
*POINTER TO REPLACE THE REMIAN BLK IN EXISTING FREE BLK LIST
*/
if(bestfit->size >= (requiredSize+8+METADATA_SIZE)){
splitNode(bestfit,requiredSize);
}
}
//size = ((size+7)/8)*8; //size alligned to 8 bytes
//printf("\nrequiredSize %d ",size);
void *ptr;
else{
/*
* since bestfit is of required size remove it form the freelist
* change required size to full block size to allocate full block since blk cant be splitted in two halves
*/
requiredSize=bestfit->size;
removeNodeFromFreeList(bestfit);
}
}
blk_header* header=NULL;
if(bestfit==NULL){
ptr=mem_sbrk(requiredSize);
MAX_ADDRESS=(char*)ptr+requiredSize;
header=(blk_header*)mem_sbrk(requiredSize);
MAX_ADDRESS=(char*)header+requiredSize;
}
else{
ptr=(void*)bestfit;
header=(blk_header*)bestfit;
}
//printf(" %d %d %p",sizeof(blk_footer),sizeof(blk_header),ptr+size+2);
//set header metadata
blk_header* header=(blk_header*)ptr;
//printf("\nheader %p ",ptr);
header->size=requiredSize;
header->free=0;
//printf("\n size %d allocated %d",header->size,header->free);
//set footer metadata
blk_footer* footer=(blk_footer*)((char*)ptr+requiredSize-sizeof(blk_footer));
blk_footer* footer=(blk_footer*)((char*)header+requiredSize-sizeof(blk_footer));
//printf("\nheader %p size %d free %dfooter size %d free %d",(void*)header,header->size,header->free,footer->size,footer->free);
footer->size=requiredSize;
footer->free=0;
//returing starting address for user data
return (void*)((char*)ptr+sizeof(blk_header));
return (void*)((char*)header+sizeof(blk_header));
//mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
......@@ -192,14 +249,24 @@ void bothfree(blk_header* left,blk_header* curr,blk_header* righthead){
free_blk_header *right=(free_blk_header*)righthead;
//Arrange pointer for right side
if(right->prev!=NULL && right->next!=NULL){
right->prev->next=right->next;
right->next->prev=right->prev;
free_blk_header *prev=right->prev;
free_blk_header *next=right->next;
//printf("\n\n prev prev%p next%p",(void*)(prev->prev),(void*)(prev->next));
//printf("\n\n next prev%p next%p",(void*)(next->prev),(void*)(next->next));
prev->next=next;
next->prev=prev;
//printf("\n\n prev prev%p next%p",(void*)(prev->next),(void*)(next->prev));
}else if(right->prev==NULL){
//printf("\n\n\n prev head %p",(void*)head);
head=right->next;
right->next->prev=NULL;
//printf("new head %p prev of head %p",(void*)head,(void*)head->prev);
}else if(right->next==NULL){
//printf("\n\n prev node %p prev new next%p",(void*)right->prev,(void*)right->prev->next);
right->prev->next=NULL;
//printf("\n\n prev node %p prev new next%p",(void*)right->prev,(void*)right->prev->next);
}
//now increase left size to leftsize+size+rightsize
......@@ -207,7 +274,7 @@ void bothfree(blk_header* left,blk_header* curr,blk_header* righthead){
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->free=1;
footer->size=left->size;
//printf("\n\n left node left %p right %p",(void*)(((free_blk_header*)left)->prev),(void*)(((free_blk_header*)left)->next));
}
void bothNotFree(blk_header *header){
int size=header->size;
......@@ -217,6 +284,7 @@ void bothNotFree(blk_header *header){
free->prev=NULL;
free->next=NULL;
//Attach block to start of list
//printf("\n\n old head %p",(void*)head);
if(head==NULL){
head=free;
}
......@@ -225,15 +293,20 @@ void bothNotFree(blk_header *header){
head->prev=free;
head=free;
}
//printf("\nnew head %p prev %p next %p",(void*)head,(void*)head->prev,(void*)head->next);
}
void leftFree(blk_header* left,blk_header* head){
//printf("\nleeft free");
//simply increase block sizze no need to change the pointers
// free_blk_header *left1=(free_blk_header*)left;
//printf("\nleft free %p prev %p next %p size %d free %d",(void*)left1,(void*)left1->prev,(void*)left1->next,left1->size,left1->free);
int size=head->size;
left->size=left->size+size;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->free=1;
footer->size=left->size;
//printf("\nleft free %p prev %p next %p size %d free %d",(void*)left1,(void*)left1->prev,(void*)left1->next,left1->size,left1->free);
}
void rightFree(blk_header* right,blk_header* currhead){
......@@ -263,11 +336,12 @@ void rightFree(blk_header* right,blk_header* currhead){
}
void mm_free(void *ptr)
{
if(ptr==NULL)
return;
blk_header *header=(blk_header*)ptr-1;
//printf("\nfree %d",header->size);
int left_free=0;
int right_free=0;
......@@ -306,19 +380,6 @@ void mm_free(void *ptr)
bothNotFree(header);
}
}
void printmem(){
blk_header *header;
char* temp=MIN_ADDRESS;
printf("\n printing mem %p",(void*)MIN_ADDRESS);
fflush(stdout);
int i=1;
while(temp<MAX_ADDRESS){
header=(blk_header*)((void*)temp);
temp=temp+header->size;
printf("\n Block %d Size %d free %d %p %p",i++,header->size,header->free,(void*)temp,(void*)MAX_ADDRESS);
}
}
/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
......@@ -333,56 +394,71 @@ void *mm_realloc(void *ptr, size_t size)
mm_free(ptr);
return NULL;
}
blk_header *curr=(blk_header*)((char*)ptr-sizeof(blk_header));
int existingBlkSize=curr->size-METADATA_SIZE;
if(size<=existingBlkSize)
return ptr;
free_blk_header *right=(free_blk_header*)((char*)curr+curr->size);
if((char*)right<MAX_ADDRESS){
if(right->free && (existingBlkSize+right->size)>=size){
//printf("\n cru free %d newsixe %d re sxer%d",right->free,existingBlkSize+right->size,size);
removeNodeFromFreeList(right);
curr->size=curr->size+right->size;
curr->free=0;
blk_footer* footer=(blk_footer*)((char*)curr+curr->size-sizeof(blk_footer));
footer->size=curr->size;
footer->free=0;
return ptr;
}
}
blk_footer *prev_footer=(blk_footer*)curr-1;
if((char*)curr!=MIN_ADDRESS){
if(prev_footer->free&& (existingBlkSize+prev_footer->size)>=size){
free_blk_header *left=(free_blk_header*)((char*)curr-prev_footer->size);
removeNodeFromFreeList(left);
left->size=curr->size+left->size;
left->free=0;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->size=left->size;
footer->free=0;
memcpy( (void*)((char*)left+sizeof(blk_header)),ptr,existingBlkSize);
return (void*)((char*)left+sizeof(blk_header));
}
}
/*
* This function should also copy the content of the previous memory block into the new block.
* You can use 'memcpy()' for this purpose.
*
* The data structures corresponding to free memory blocks and allocated memory
* blocks should also be updated.
*/
int bytesToCopy=existingBlkSize;
if(existingBlkSize>size)
bytesToCopy=size;
void* memory=mm_malloc(size);
memcpy(memory,ptr,((blk_header*)ptr-1)->size);
memcpy(memory,ptr,bytesToCopy);
mm_free(ptr);
return memory;
}
/*
int main(){
mem_init();
mm_init();
void *temp0=mm_malloc(4);
//printmem();
void *temp=mm_malloc(4);
//printmem();
void* temp2=mm_malloc(4);
//printmem();
mm_free(temp2);
//printmem();
mm_malloc(7);
//printmem();
mm_free(temp2);
mm_free(temp);
//printmem();
mm_realloc(temp0,14);
//printmem();
void printmem(){
blk_header *header;
char* temp=MIN_ADDRESS;
printf("\n printing mem %p",(void*)MIN_ADDRESS);
fflush(stdout);
int i=1;
while(temp<MAX_ADDRESS){
header=(blk_header*)((void*)temp);
temp=temp+header->size;
printf("\n Block %d Size %d free %d %p alinged %d ",i++,header->size,header->free,(void*)header,((intptr_t)(header+1)) % 8);
}
}
*/
void printfreeList(){
free_blk_header *header=head;
printf("\n printing freelist mem %p",(void*)head);
fflush(stdout);
int i=1;
while(header!=NULL){
printf("\n free Block %d Size %d free %d %p ",i++,header->size,header->free,(void*)header);
header=header->next;
}
}
/*
* mm-naive.c - The fastest, least memory-efficient malloc package.
*
* In this naive approach, a block is allocated by simply incrementing
* the brk pointer. A block is pure payload. There are no headers or
* footers. Blocks are never coalesced or reused. Realloc is
* implemented directly using mm_malloc and mm_free.
*
* NOTE TO STUDENTS: Replace this header comment with your own header
* comment that gives a high level description of your solution.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include "mm.h"
#include "memlib.h"
/*********************************************************
* NOTE TO STUDENTS: Before you do anything else, please
* provide your team information in the following struct.
********************************************************/
team_t team = {
/* Team name */
"team name",
"Boolean Pundits",
/* First member's full name */
"paras garg",
/* First member's email address */
"parasgarg@cse.iitb.ac.in",
/* Second member's full name (leave blank if none) */
"Ketan shashikant kulkarni",
"Ketan kulkarni",
/* Second member's email address (leave blank if none) */
"member_2@cse.iitb.ac.in"
"ketankulkarni@cse.iitb.ac.in"
};
/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
#define HEIGHT(node) (node==NULL?0:node->height)
typedef struct blk_header_t {
int free;
int size;
}blk_header;
//size of struct on 32bit system is 20 byte
typedef struct free_blk_header_t {
int free;
int size;
struct free_blk_header_t *prev;
struct free_blk_header_t *next;
}free_blk_header;
//size of struct on 32 bit system is 8 byte
typedef struct blk_footer_t {
int free;
size_t size;
}blk_footer;
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
typedef struct seg_t{
free_blk_header* head;
}seg;
seg *segList;
#define N_SEG_LIST 10
int METADATA_SIZE;
int MIN_BLOCK_SIZE;
free_blk_header *root=NULL;
/*
* mm_init - initialize the malloc package.
*/
char* MAX_ADDRESS;
char* MIN_ADDRESS;
void *init_mem_sbrk_break = NULL;
//function signature
void insertNodeAtFirst(free_blk_header *curr,int bin);
void removeNodeFromSegList(free_blk_header *node,int bin);
int getBin(int i);
void splitAndInsertRemainAtHead(free_blk_header *bestfit,int requiredSize);
void printmem();
free_blk_header* getBestFit(int requiredSize);
int mm_init(void)
{
segList=mem_sbrk(N_SEG_LIST*sizeof(seg));
for(int i=0;i<N_SEG_LIST;i++)
segList[i].head=NULL;
for(int i=0;i<N_SEG_LIST;i++)
//printf("%p",segList[i].head);
METADATA_SIZE=sizeof(blk_header)+sizeof(blk_footer);
MIN_BLOCK_SIZE=METADATA_SIZE+8;
MIN_ADDRESS=mem_sbrk(0);
MAX_ADDRESS=MIN_ADDRESS;
if(MIN_ADDRESS==NULL)
return 1;
return 0;
}
int getBin(int i){
if(i==24)
return 0;
int l=0;
while (i >>= 1) { ++l; }
if(l>N_SEG_LIST+4)
return 9;
return l-5;
}
void insertNodeAtFirst(free_blk_header *curr,int bin){
curr->prev=NULL;
curr->free=1;
free_blk_header *head=segList[bin].head;
//This function is called every time before each test run of the trace.
//It should reset the entire state of your malloc or the consecutive trace runs will give wrong answer.
if(head!=NULL){
curr->next=head;
head->prev=curr;
}else{
curr->next=NULL;
}
segList[bin].head=curr;
}
/*
* This function should initialize and reset any data structures used to represent the starting state(empty heap)
*
* This function will be called multiple time in the driver code "mdriver.c"
*/
void removeNodeFromSegList(free_blk_header * node,int bin){
if(node->prev==NULL && node->next==NULL){
//printf("\n\n single node case bestfit %p",(void*)bestfit);
segList[bin].head=NULL;
//case b firs node
}else if(node->prev==NULL){
free_blk_header *nextNode=node->next;
segList[bin].head=nextNode;
nextNode->prev=NULL;
//printf("\n\nfirst node %pnew head %p head prev%p head next%p",(void*)bestfit,(void*)head,(void*)head->prev,(void*)head->next);
//case c last node
}else if(node->next==NULL){
free_blk_header *prevNode=node->prev;
prevNode->next=NULL;
//printf("\n\n last node %p prevnode %p",(void*)bestfit,(void*)prevNode);
//case d middle node
}else{
free_blk_header *nextNode=node->next;
free_blk_header *prevNode=node->prev;
nextNode->prev=prevNode;
prevNode->next=nextNode;
//printf("\n\n middle node %p prevnode next %p nextnode prev%p",(void*)bestfit,(void*)prevNode->next,(void*)nextNode->prev);
}
}
void splitAndInsertRemainAtHead(free_blk_header *bestfit,int requiredSize){
int remainSize=bestfit->size-requiredSize;
bestfit->size=requiredSize;
return 0; //Returns 0 on successfull initialization.
free_blk_header *remain=(free_blk_header*)((char*)bestfit+requiredSize);
remain->size=remainSize;
blk_footer* footer=(blk_footer*)((char*)remain+remain->size-sizeof(blk_footer));
footer->size=remain->size;
footer->free=1;
insertNodeAtFirst(remain,getBin(remainSize));
}
//---------------------------------------------------------------------------------------------------------------
/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment.
free_blk_header* getBestFit(int requiredSize){
int bin=getBin(requiredSize);
free_blk_header *list=segList[bin].head;
free_blk_header *bestfit=NULL;
//printf("\nmalloc reg bin %d",bin);
while(list!=NULL){
if(list->size>=requiredSize){
bestfit=list;
break;
//code to find bestfit
/*if(bestfit!=NULL){
if(list->size<bestfit->size)
bestfit=list;
}else{
bestfit=list;
}*/
}
list=list->next;
}
if(bestfit!=NULL){
removeNodeFromSegList(bestfit,bin);
return bestfit;
}
/*
*Since,bestfit/firstfit is not found in given list go for next higher fit and split node if new node size>required size since requiredSize=METADATA_SIZE+ALIGN(Size) .so.2 times of it can hold 2 METADATA and 2 ALIGN(SiZE)
*/
bin++;
while(bin<N_SEG_LIST){
if(segList[bin].head!=NULL){
bestfit=segList[bin].head;
break;
}
bin++;
}
if(bestfit!=NULL){
removeNodeFromSegList(bestfit,bin);
if( bestfit->size >= 2*requiredSize){
///printf("\nreq size%d new size%d",requiredSize,bestfit->size);
splitAndInsertRemainAtHead(bestfit,requiredSize);
}
}
return bestfit;
}
void *mm_malloc(size_t size)
{
/*
* This function should keep track of the allocated memory blocks.
* The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory.
* The previously freed memory blocks should be reused.
* If no appropriate free block is available then the increase the heap size using 'mem_sbrk(size)'.
* Try to keep the heap size as small as possible.
*/
//printmem();
if(size <= 0){ // Invalid request size
return NULL;
}
size = ((size+7)/8)*8; //size alligned to 8 bytes
return mem_sbrk(size); //mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
int requiredSize=ALIGN(size)+METADATA_SIZE;
free_blk_header *bestfit=getBestFit(requiredSize);
if(bestfit!=NULL){
//to avoid internal memory leaking beacause due to align and avoided splitiing block may contain extra splace that leads to imternal fragmentation but that is manageable.
requiredSize=bestfit->size;
}
blk_header *header=(blk_header*)bestfit;
//printf("\n block header %p",header);
if(header==NULL){
header=(blk_header*)mem_sbrk(requiredSize);
//set uper limit of allocated address
MAX_ADDRESS=(char*)header+requiredSize;
}
//printf("\n block header %p",header);
//printf("\n req size %d",requiredSize);
header->size=requiredSize;
header->free=0;
blk_footer* footer=(blk_footer*)((char*)header+requiredSize-sizeof(blk_footer));
footer->size=requiredSize;
footer->free=0;
//printf("\nheader %p size %d free %dfooter size %d free %d",(void*)header,header->size,header->free,footer->size,footer->free);
//returing starting address for user data
return (void*)((char*)header+sizeof(blk_header));
}
void mm_free(void *ptr)
{
if(ptr==NULL)
return;
free_blk_header *curr=(free_blk_header*)((char*)ptr-sizeof(blk_header));
free_blk_header *right=(free_blk_header*)((char*)ptr-sizeof(blk_header)+curr->size);
int rightfree=0;
if((char*)right<MAX_ADDRESS){
if(right->free)
rightfree=1;
}
int leftfree=0;
free_blk_header *left=NULL;
if((char*)curr!=MIN_ADDRESS){
blk_footer *leftFooter=(blk_footer*)((char*)curr-sizeof(blk_footer));
if(leftFooter->free){
leftfree=1;
left=(free_blk_header*)((char*)curr-leftFooter->size);
}
}
if(leftfree && rightfree){
int leftbin=getBin(left->size);
int rightbin=getBin(right->size);
removeNodeFromSegList(left,leftbin);
removeNodeFromSegList(right,rightbin);
left->size=curr->size+left->size+right->size;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->size=left->size;
footer->free=1;
insertNodeAtFirst(left,getBin(left->size));
}
else if(leftfree){
int leftbin=getBin(left->size);
removeNodeFromSegList(left,leftbin);
left->size=curr->size+left->size;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->size=left->size;
footer->free=1;
insertNodeAtFirst(left,getBin(left->size));
}
else if(rightfree){
int rightbin=getBin(right->size);
removeNodeFromSegList(right,rightbin);
curr->size=curr->size+right->size;
blk_footer* footer=(blk_footer*)((char*)curr+curr->size-sizeof(blk_footer));
footer->size=curr->size;
footer->free=1;
insertNodeAtFirst(curr,getBin(curr->size));
}
else{
int bin=getBin(curr->size);
blk_footer* footer=(blk_footer*)((char*)curr+curr->size-sizeof(blk_footer));
footer->size=curr->size;
footer->free=1;
insertNodeAtFirst(curr,bin);
}
/*
* Searches the previously allocated node for memory block with base address ptr.
*
......@@ -106,13 +298,8 @@ void mm_free(void *ptr)
*/
}
/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/
void *mm_realloc(void *ptr, size_t size)
{
size = ((size+7)/8)*8; //8-byte alignement
if(ptr == NULL){ //memory was not previously allocated
return mm_malloc(size);
}
......@@ -121,30 +308,64 @@ void *mm_realloc(void *ptr, size_t size)
mm_free(ptr);
return NULL;
}
/*
* This function should also copy the content of the previous memory block into the new block.
* You can use 'memcpy()' for this purpose.
*
* The data structures corresponding to free memory blocks and allocated memory
* blocks should also be updated.
*/
mm_free(ptr);
return mem_sbrk(size);
}
blk_header *curr=(blk_header*)((char*)ptr-sizeof(blk_header));
int existingBlkSize=curr->size-METADATA_SIZE;
if(size<=existingBlkSize)
return ptr;
/*free_blk_header *right=(free_blk_header*)((char*)curr+curr->size);
if((char*)right<MAX_ADDRESS){
if(right->free && (existingBlkSize+right->size-METADATA_SIZE)>=size){
//printf("\n cru free %d newsixe %d re sxer%d",right->free,existingBlkSize+right->size,size);
int rightbin=getBin(right->size);
removeNodeFromSegList(right,rightbin);
curr->size=curr->size+right->size;
curr->free=0;
blk_footer* footer=(blk_footer*)((char*)curr+curr->size-sizeof(blk_footer));
footer->size=curr->size;
footer->free=0;
return ptr;
}
}*/
if((char*)curr!=MIN_ADDRESS){
blk_footer *leftFooter=(blk_footer*)((char*)curr-sizeof(blk_footer));
free_blk_header *left=(free_blk_header*)((char*)curr-leftFooter->size);
if(leftFooter->free && (existingBlkSize+left->size-METADATA_SIZE)>=size){
int leftbin=getBin(left->size);
removeNodeFromSegList(left,leftbin);
left->size=curr->size+left->size;
left->free=0;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->size=left->size;
footer->free=0;
memcpy( (void*)((char*)left+sizeof(blk_header)),ptr,existingBlkSize);
return (void*)((char*)left+sizeof(blk_header));
}
}
int bytesToCopy=existingBlkSize;
if(existingBlkSize>size)
bytesToCopy=size;
void* memory=mm_malloc(size);
memcpy(memory,ptr,bytesToCopy);
mm_free(ptr);
return memory;
}
void printmem(){
blk_header *header;
char* temp=MIN_ADDRESS;
printf("\n printing mem %p",(void*)MIN_ADDRESS);
fflush(stdout);
int i=1;
header=(blk_header*)((void*)temp);
while(temp<MAX_ADDRESS){
temp=temp+header->size;
printf("\n Block %d Size %d free %d %p alinged %d ",i++,header->size,header->free,(void*)header,((intptr_t)(header+1)) % 8);
}
}
File deleted
#ifndef __CONFIG_H_
#define __CONFIG_H_
/*
* config.h - malloc lab configuration file
*
* Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*/
/*
* This is the default path where the driver will look for the
* default tracefiles. You can override it at runtime with the -t flag.
*/
#define TRACEDIR "/afs/cs/project/ics2/im/labs/malloclab/traces/"
/*
* This is the list of default tracefiles in TRACEDIR that the driver
* will use for testing. Modify this if you want to add or delete
* traces from the driver's test suite. For example, if you don't want
* your students to implement realloc, you can delete the last two
* traces.
*/
#define DEFAULT_TRACEFILES \
"amptjp-bal.rep",\
"cccp-bal.rep",\
"cp-decl-bal.rep",\
"expr-bal.rep",\
"coalescing-bal.rep",\
"random-bal.rep",\
"random2-bal.rep",\
"binary-bal.rep",\
"binary2-bal.rep",\
"realloc-bal.rep",\
"realloc2-bal.rep"
/*
* This constant gives the estimated performance of the libc malloc
* package using our traces on some reference system, typically the
* same kind of system the students use. Its purpose is to cap the
* contribution of throughput to the performance index. Once the
* students surpass the AVG_LIBC_THRUPUT, they get no further benefit
* to their score. This deters students from building extremely fast,
* but extremely stupid malloc packages.
*/
#define AVG_LIBC_THRUPUT 600E3 /* 600 Kops/sec */
/*
* This constant determines the contributions of space utilization
* (UTIL_WEIGHT) and throughput (1 - UTIL_WEIGHT) to the performance
* index.
*/
#define UTIL_WEIGHT .60
/*
* Alignment requirement in bytes (either 4 or 8)
*/
#define ALIGNMENT 8
/*
* Maximum heap size in bytes
*/
#define MAX_HEAP (20*(1<<20)) /* 20 MB */
/*****************************************************************************
* Set exactly one of these USE_xxx constants to "1" to select a timing method
*****************************************************************************/
#define USE_FCYC 0 /* cycle counter w/K-best scheme (x86 & Alpha only) */
#define USE_ITIMER 0 /* interval timer (any Unix box) */
#define USE_GETTOD 1 /* gettimeofday (any Unix box) */
#endif /* __CONFIG_H */
/*
* memlib.c - a module that simulates the memory system. Needed because it
* allows us to interleave calls from the student's malloc package
* with the system's malloc package in libc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include "memlib.h"
#include "config.h"
/* private variables */
static char *mem_start_brk; /* points to first byte of heap */
static char *mem_brk; /* points to last byte of heap */
static char *mem_max_addr; /* largest legal heap address */
/*
* mem_init - initialize the memory system model
*/
void mem_init(void)
{
/* allocate the storage we will use to model the available VM */
if ((mem_start_brk = (char *)malloc(MAX_HEAP)) == NULL) {
fprintf(stderr, "mem_init_vm: malloc error\n");
exit(1);
}
mem_max_addr = mem_start_brk + MAX_HEAP; /* max legal heap address */
mem_brk = mem_start_brk; /* heap is empty initially */
}
/*
* mem_deinit - free the storage used by the memory system model
*/
void mem_deinit(void)
{
free(mem_start_brk);
}
/*
* mem_reset_brk - reset the simulated brk pointer to make an empty heap
*/
void mem_reset_brk()
{
mem_brk = mem_start_brk;
}
/*
* mem_sbrk - simple model of the sbrk function. Extends the heap
* by incr bytes and returns the start address of the new area. In
* this model, the heap cannot be shrunk.
*/
void *mem_sbrk(int incr)
{
char *old_brk = mem_brk;
if ( (incr < 0) || ((mem_brk + incr) > mem_max_addr)) {
errno = ENOMEM;
fprintf(stderr, "ERROR: mem_sbrk failed. Ran out of memory...\n");
return (void *)-1;
}
mem_brk += incr;
return (void *)old_brk;
}
/*
* mem_heap_lo - return address of the first heap byte
*/
void *mem_heap_lo()
{
return (void *)mem_start_brk;
}
/*
* mem_heap_hi - return address of last heap byte
*/
void *mem_heap_hi()
{
return (void *)(mem_brk - 1);
}
/*
* mem_heapsize() - returns the heap size in bytes
*/
size_t mem_heapsize()
{
return (size_t)(mem_brk - mem_start_brk);
}
/*
* mem_pagesize() - returns the page size of the system
*/
size_t mem_pagesize()
{
return (size_t)getpagesize();
}
#include <unistd.h>
void mem_init(void);
void mem_deinit(void);
void *mem_sbrk(int incr);
void mem_reset_brk(void);
void *mem_heap_lo(void);
void *mem_heap_hi(void);
size_t mem_heapsize(void);
size_t mem_pagesize(void);
#include <stdio.h>
extern int mm_init (void);
extern void *mm_malloc (size_t size);
extern void mm_free (void *ptr);
extern void *mm_realloc(void *ptr, size_t size);
/*
* Students work in teams of one or two. Teams enter their team name,
* personal names and login IDs in a struct of this
* type in their bits.c file.
*/
typedef struct {
char *teamname; /* ID1+ID2 or ID1 */
char *name1; /* full name of first member */
char *id1; /* login ID of first member */
char *name2; /* full name of second member (if any) */
char *id2; /* login ID of second member */
} team_t;
extern team_t team;
/********************************************************************************************************
* mm use Header and footer for each block allocated/non allocated
* footer helps to insert in free list in 0(1) time
* also two-sided coalescing can be done in 0(1) time
* freelist uses double-linked list
* if either or both adjacent block are free it willbe merged with them
* else block will be attached to head of list
* free call will take o(1) time for coalescing andd insertion
* MM_malloc first search for a block in free list if avilable using best first it will return
* if not available new block will be requested from mem_sbrk
*Metadata size in allocated block is 8(footer)+8(header)=16 byte
* min block size will be !6 +8(min size after align)=24 byte
*metadata size for free block will be 16(header)+8(footer)=24 byte
*since min block size is guaranted to be 24 hence metadata for free block can be stored easily
*in giveen space
********************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include "mm.h"
#include "memlib.h"
team_t team = {
/* Team name */
"team",
/* First member's full name */
"Paras Garg",
/* First member's email address */
"parasgarg@cse.iitb.ac.in",
/* Second member's full name (leave blank if none) */
"member 2",
/* Second member's email address (leave blank if none) */
"member_2@cse.iitb.ac.in"
};
/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
#define ALLOC_UNIT sysconf(_SC_PAGESIZE)
//size of struct on 32bit system is 8 byte
typedef struct blk_header_t {
size_t size;
int free;
}blk_header;
//size of struct on 32bit system is 16 byte
typedef struct free_blk_header_t {
size_t size;
int free;
struct free_blk_header_t *prev;
struct free_blk_header_t *next;
}free_blk_header;
//size of struct on 32 bit system is 8 byte
typedef struct blk_footer_t {
int free;
size_t size;
}blk_footer;
#define METADATA_SIZE (sizeof(blk_footer)+sizeof(blk_header))
free_blk_header *head;
char* MAX_ADDRESS;
char* MIN_ADDRESS;
void *init_mem_sbrk_break = NULL;
/*
* mm_init - initialize the malloc package.
*/
int mm_init(void)
{
head=NULL;
MIN_ADDRESS=mem_sbrk(0);
//printf("ini%p",(void*)MIN_ADDRESS);
//printf("starting address %p",(void*)MIN_ADDRESS);
MAX_ADDRESS=MIN_ADDRESS;
/*
* IT resest the head of freelist to null
* memlib reset the heap section used resetting head do the work
*/
return 0; //Returns 0 on successfull initialization.
}
//---------------------------------------------------------------------------------------------------------------
/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment.
*/
void *mm_malloc(size_t size)
{
/*
* This function should keep track of the allocated memory blocks.
* The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory.
* The previously freed memory blocks should be reused.
* If no appropriate free block is available then the increase the heap size using 'mem_sbrk(size)'.
* Try to keep the heap size as small as possible.
*/
//printf("\n allocating %d",size);
if(size <= 0){ // Invalid request size
return NULL;
}
size=ALIGN(size);
int requiredSize=size+METADATA_SIZE;
free_blk_header *temp=head;
free_blk_header *bestfit=NULL;
while(temp!=NULL){
// printf("\n freelist search block address %p size %d",(void*)temp,temp->size);
fflush(stdout);
if(temp->size >= requiredSize){
if(bestfit==NULL){
bestfit=temp;
}
else if(bestfit->size>temp->size){
bestfit=temp;
}
}
temp=temp->next;
}
if(bestfit!=NULL){
//because block size may be greater and hence
requiredSize=bestfit->size;
//printf("\n block mil gaya");
free_blk_header *prev=bestfit->prev;
temp=bestfit->next;
if(prev==NULL){
if(temp==NULL){
head=NULL;
}else{
head=temp;
temp->prev=NULL;
}
}else{
if(temp==NULL){
prev->next=NULL;
}else{
prev->next=temp;
temp->prev=prev;
}
}
}
//size = ((size+7)/8)*8; //size alligned to 8 bytes
//printf("\nrequiredSize %d ",size);
void *ptr;
if(bestfit==NULL){
ptr=mem_sbrk(requiredSize);
MAX_ADDRESS=(char*)ptr+requiredSize;
}
else{
ptr=(void*)bestfit;
}
//printf(" %d %d %p",sizeof(blk_footer),sizeof(blk_header),ptr+size+2);
//set header metadata
blk_header* header=(blk_header*)ptr;
//printf("\nheader %p ",ptr);
header->size=requiredSize;
header->free=0;
//printf("\n size %d allocated %d",header->size,header->free);
//set footer metadata
blk_footer* footer=(blk_footer*)((char*)ptr+requiredSize-sizeof(blk_footer));
//printf("\nheader %p size %d free %dfooter size %d free %d",(void*)header,header->size,header->free,footer->size,footer->free);
footer->size=requiredSize;
footer->free=0;
//returing starting address for user data
return (void*)((char*)ptr+sizeof(blk_header));
//mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
}
void bothfree(blk_header* left,blk_header* curr,blk_header* righthead){
free_blk_header *right=(free_blk_header*)righthead;
//Arrange pointer for right side
if(right->prev!=NULL && right->next!=NULL){
right->prev->next=right->next;
right->next->prev=right->prev;
}else if(right->prev==NULL){
head=right->next;
right->next->prev=NULL;
}else if(right->next==NULL){
right->prev->next=NULL;
}
//now increase left size to leftsize+size+rightsize
left->size=left->size+curr->size+right->size;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->free=1;
footer->size=left->size;
}
void bothNotFree(blk_header *header){
int size=header->size;
free_blk_header *free=(free_blk_header*)((void*)header);
free->size=size;
free->free=1;
free->prev=NULL;
free->next=NULL;
//Attach block to start of list
if(head==NULL){
head=free;
}
else{
free->next=head;
head->prev=free;
head=free;
}
}
void leftFree(blk_header* left,blk_header* head){
//printf("\nleeft free");
//simply increase block sizze no need to change the pointers
int size=head->size;
left->size=left->size+size;
blk_footer* footer=(blk_footer*)((char*)left+left->size-sizeof(blk_footer));
footer->free=1;
footer->size=left->size;
}
void rightFree(blk_header* right,blk_header* currhead){
//printf("right free");
int size=currhead->size;
free_blk_header *prev=((free_blk_header*)right)->prev;
free_blk_header *next=((free_blk_header*)right)->next;
int rightsize=right->size;
//set footer
blk_footer* footer=(blk_footer*)((char*)right+right->size-sizeof(blk_footer));
footer->size=rightsize+size;
//set header
free_blk_header *current=(free_blk_header*)currhead;
current->free=1;
current->size=rightsize+size;
current->next=next;
if(next!=NULL)
next->prev=current;
current->prev=prev;
if(prev!=NULL){
prev->next=current;
}else{
head=current;
}
}
void mm_free(void *ptr)
{
if(ptr==NULL)
return;
blk_header *header=(blk_header*)ptr-1;
int left_free=0;
int right_free=0;
blk_header *rightHead=(blk_header*)((char*)header+header->size);
if((char*)rightHead!=MAX_ADDRESS){
//printf("right head exists");
if(rightHead->free)
right_free=1;
}
blk_footer *prev_footer=(blk_footer*)header-1;
blk_header *leftHead=(blk_header*)((char*)header-prev_footer->size);
// printf("prev head %p prev footer%p free %d next head%p free%d",(void*)leftHead,(void*)prev_footer,prev_footer->free,(void*)rightHead,rightHead->free);
if((char*)header!=MIN_ADDRESS){
//printf("left head exists");
if(leftHead->free)
left_free=1;
}
// printf("\n right starting address %p size %d free %d",(void*)rightHead,rightHead->size,rightHead->free);
//printf("\n left starting address %p size %d free %d",(void*)leftHead,leftHead->size,leftHead->free);
/*
* finding both adjacents blocks
* and check whether both are free
*/
if(left_free==1 && right_free==1){
bothfree(leftHead,header,rightHead);
}
if(left_free==0 && right_free==1){
rightFree(rightHead,header);
}
if(left_free==1 && right_free==0){
leftFree(leftHead,header);
}
if(left_free==0 && right_free==0){
bothNotFree(header);
}
}
void printmem(){
blk_header *header;
char* temp=MIN_ADDRESS;
printf("\n printing mem %p",(void*)MIN_ADDRESS);
fflush(stdout);
int i=1;
while(temp<MAX_ADDRESS){
header=(blk_header*)((void*)temp);
temp=temp+header->size;
printf("\n Block %d Size %d free %d %p %p",i++,header->size,header->free,(void*)temp,(void*)MAX_ADDRESS);
}
}
/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/
void *mm_realloc(void *ptr, size_t size)
{
if(ptr == NULL){ //memory was not previously allocated
return mm_malloc(size);
}
if(size == 0){ //new size is zero
mm_free(ptr);
return NULL;
}
/*
* This function should also copy the content of the previous memory block into the new block.
* You can use 'memcpy()' for this purpose.
*
* The data structures corresponding to free memory blocks and allocated memory
* blocks should also be updated.
*/
void* memory=mm_malloc(size);
memcpy(memory,ptr,((blk_header*)ptr-1)->size);
mm_free(ptr);
return memory;
}
/*
int main(){
mem_init();
mm_init();
void *temp0=mm_malloc(4);
//printmem();
void *temp=mm_malloc(4);
//printmem();
void* temp2=mm_malloc(4);
//printmem();
mm_free(temp2);
//printmem();
mm_malloc(7);
//printmem();
mm_free(temp2);
mm_free(temp);
//printmem();
mm_realloc(temp0,14);
//printmem();
}
*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment