Commit 98d0a4ad authored by Shivaji's avatar Shivaji

Update mm1.c

parent 274a4464
......@@ -112,6 +112,21 @@ uint32_t block_size;
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
#define TOTAL_COMBINE_SIZE_OF_BLOCKS(base) \
base->block_size \
+sizeof(block_end_meta_data_t) \
+sizeof(block_meta_data_t)
#define TOTAL_COMBINED_SIZE_OF_BLOCKS(base) \
base->next_block->block_size \
+base->prev_block->block_size \
+2*sizeof(block_end_meta_data_t) \
+2*sizeof(block_meta_data_t)
#define META_DATA_OVERHEAD \
(uint32_t)(sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t))
/*
* mm_init - initialize the malloc package.
*/
......@@ -180,7 +195,11 @@ void insert_node_in_freelist(free_node_t **head,block_meta_data_t *new_metadata_
}
new_metadata_block->free_node.next_node=next_node;
if(next_node)
next_node->prev_node = &(new_metadata_block->free_node);
new_metadata_block->free_node.prev_node=prev_node;
if(prev_node)
prev_node->next_node = &(new_metadata_block->free_node);
}
}
......@@ -258,6 +277,14 @@ void remove_block_from_free_list(free_node_t **head,free_node_t *del_node)
}
del_node->prev_node=NULL;
del_node->next_node=NULL;
free_node_t *head1=*head;
// while (head1)
// {
// block_meta_data_t *trace = (block_meta_data_t *)meta_data_block_addr(head1);
// printf("%d [FREE BLOCK SIZE]\n",trace->block_size);
// head1 = head1->next_node;
// }
}
int get_internal_fragmented_size(block_meta_data_t *block1,block_meta_data_t *block2)
......@@ -269,6 +296,41 @@ int get_internal_fragmented_size(block_meta_data_t *block1,block_meta_data_t *bl
}
void *allocate_requested_size(size_t size)
{
size_t sys_page_size=mem_pagesize();
int no_of_pages_req=((size+sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t)+sys_page_size-1)/sys_page_size);
size_t extra_size_req=(int)no_of_pages_req*sys_page_size;
void *brk= mem_sbrk(extra_size_req);
if(*(int *)brk==-1)
return NULL;
return brk;
}
void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_block,block_meta_data_t *free_block,uint32_t final_remain,int c)
{
block_meta_data_t *new_block = (block_meta_data_t *)NEXT_META_BLOCK_BY_SIZE(meta_data_block);
// printf("%d[NEW BLOCK BEFORE SIZE]\n", new_block->block_size);
if(meta_data_block->is_free == MM_TRUE)
meta_data_block->is_free = MM_FALSE;
if(c == 0)
{
meta_data_block->next_block = free_block->next_block->next_block;
}
else
{
meta_data_block->next_block = free_block->next_block;
new_block->block_size = (uint32_t)final_remain;
}
new_block->free_node = init_free_node();
new_block->is_free = MM_TRUE;
mm_bind_blocks_for_allocation(meta_data_block, new_block);
assert(meta_data_block->next_block->block_size == new_block->block_size);
block_end_meta_data_t *new_end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(new_block);
new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(head,new_block);
}
int mm_init(void)
{
......@@ -332,17 +394,7 @@ void *mm_malloc(size_t size)
if(free_metadata_block==NULL)
{
size_t sys_page_size=mem_pagesize();
int no_of_pages_req=((size+sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t)+sys_page_size-1)/sys_page_size);
size_t extra_size_req=(int)no_of_pages_req*sys_page_size;
void *brk= mem_sbrk(extra_size_req);
if(*(int *)brk==-1)
{
return NULL;
}
void *brk = allocate_requested_size(size);
block_end_meta_data_t *prev_end_meta_data=NULL;
......@@ -374,7 +426,9 @@ void *mm_malloc(size_t size)
new_free_meta_block->is_free=MM_TRUE;
new_free_meta_block->block_size=(uint32_t)(extra_size_req-size-(2*sizeof(block_meta_data_t))-(2*sizeof(block_end_meta_data_t)));
// new_free_meta_block->block_size=(uint32_t)(extra_size_req-size-(2*sizeof(block_meta_data_t))-(2*sizeof(block_end_meta_data_t)));
new_free_meta_block->block_size= (uint32_t)((char *)mem_heap_hi()-(char *)brk+1-size-(2*(uint32_t)sizeof(block_meta_data_t))-(2*(uint32_t)sizeof(block_end_meta_data_t)));
new_free_meta_block->free_node=init_free_node();
......@@ -414,6 +468,7 @@ void *mm_malloc(size_t size)
block_end_meta_data_t *next_end_meta_block=NULL;
// printf("%p %d %u[CHECKING NECT_BLOCK_BY_SIZE]\n",(char *)(free_metadata_block+1), free_metadata_block->block_size , sizeof(block_end_meta_data_t));
next_meta_block=NEXT_META_BLOCK_BY_SIZE(free_metadata_block);
next_meta_block->is_free=MM_TRUE;
......@@ -426,9 +481,12 @@ void *mm_malloc(size_t size)
next_end_meta_block->block_size=next_meta_block->block_size;
insert_node_in_freelist(head,next_meta_block);
mm_bind_blocks_for_allocation(free_metadata_block,next_meta_block);
}
......@@ -506,6 +564,7 @@ void mm_free(void *ptr)
merged_end_meta_data_block->block_size=merged_meta_data_block->block_size;
// printf("%d %d [AFTER MERGINGN FAILING HERE]\n",merged_meta_data_block->block_size);
insert_node_in_freelist(head,merged_meta_data_block);
}
......@@ -516,8 +575,22 @@ void mm_free(void *ptr)
*/
void *mm_realloc(void *ptr, size_t size)
{
/*
* 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);
size = ((size+7)/8)*8; //8-byte alignement
// printf("%lu [SIZE AFTER ALIGNMNET]",size);
if(ptr == NULL){ //memory was not previously allocated
return mm_malloc(size);
}
......@@ -527,16 +600,161 @@ void *mm_realloc(void *ptr, size_t size)
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.
*/
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t));
mm_free(ptr);
return mem_sbrk(size);
if(size == meta_data_block->block_size)
return meta_data_block;
// if provided size is less than already allocated size `if block` will be executed otherwiae `else block`.
if(size < meta_data_block->block_size)
{
uint32_t original_size = (uint32_t)meta_data_block->block_size;
uint32_t inter_frag = (uint32_t)get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
meta_data_block->block_size = size;
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
end_meta_data_block->block_size = meta_data_block->block_size;
if(meta_data_block->next_block && meta_data_block->next_block->is_free==MM_TRUE)
{
block_meta_data_t *new_block = NEXT_META_BLOCK_BY_SIZE(meta_data_block);
remove_block_from_free_list(head, &meta_data_block->next_block->free_node);
// printf("%d %d %d\n", meta_data_block->next_block->block_size , inter_frag , (original_size-size));
new_block->block_size = meta_data_block->next_block->block_size + inter_frag + (original_size - size);
// printf("%d [AFTER REALLOC]\n",new_block->block_size);
new_block->is_free = MM_TRUE;
new_block->free_node= init_free_node();
mm_bind_blocks_for_allocation(meta_data_block, new_block);
block_end_meta_data_t *new_end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(new_block);
new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(head,new_block);
// printf("%u [NEW FREE BLOCK SIZE ]\n %u [OLD BLOCK SIZE] \n",meta_data_block->next_block->block_size, meta_data_block->block_size);
return (void *)(meta_data_block+1);
}
else
{
uint32_t inter_frag =0;
int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t)));
if(!meta_data_block->next_block){
if( (fragmented_size+original_size-size) < (sizeof(block_end_meta_data_t)+sizeof(end_meta_data_block)) )
return meta_data_block;
}
else{
uint32_t inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
if( (inter_frag+original_size-size) < (sizeof(block_end_meta_data_t)+sizeof(end_meta_data_block)) )
return meta_data_block;
fragmented_size = 0;
}
meta_data_block->block_size = size;
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
end_meta_data_block->block_size = meta_data_block->block_size;
if((original_size- size + inter_frag + fragmented_size) > META_DATA_OVERHEAD)
{
block_meta_data_t *new_block = (block_meta_data_t *)NEXT_META_BLOCK_BY_SIZE(meta_data_block);
new_block->free_node = init_free_node();
new_block->is_free = MM_TRUE;
new_block->block_size = original_size- size + inter_frag + fragmented_size - META_DATA_OVERHEAD;
mm_bind_blocks_for_allocation(meta_data_block, new_block);
block_end_meta_data_t *new_end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(new_block);
new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(head,new_block);
}
return (void *)(meta_data_block+1);
}
}
else
{
uint32_t req_rem_size = size-meta_data_block->block_size;
uint32_t inter_frag = 0;
if(meta_data_block->next_block)
inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
else
inter_frag = (uint32_t)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t)));
if(req_rem_size <= inter_frag)
{
// TODO check sizeof function once
meta_data_block->block_size += req_rem_size;
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
end_meta_data_block->block_size = meta_data_block->block_size;
return (void *)(meta_data_block+1); // Not handling adding remaining free part to free list because it is small in size to handle even headers, so skkipping.
}
if(meta_data_block->next_block && meta_data_block->next_block->is_free == MM_TRUE && \
req_rem_size <= (TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->next_block)+inter_frag))
{
// printf("%p [IN REALLAOC]\n",&meta_data_block->next_block->free_node);
remove_block_from_free_list(head,&meta_data_block->next_block->free_node);
uint32_t final_remain = TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->next_block) - req_rem_size;
meta_data_block->block_size += req_rem_size;
req_rem_size -= inter_frag;
// printf("%d [FINAL REMAINING] %d [ALLTED BLOCK SIZE]\n",final_remain, meta_data_block->block_size);
// printf("%d [SIZE TO REMOVED FROM FREE LIST]\n", meta_data_block->next_block->block_size);
// printf("[REMOVED$$$$$$$$$$$$$$$$$]\n");
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
end_meta_data_block->block_size = meta_data_block->block_size;
if( final_remain > META_DATA_OVERHEAD)
{
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1);
}
return (void *)(meta_data_block+1);
}
if(meta_data_block->prev_block && meta_data_block->prev_block->is_free == MM_TRUE && \
req_rem_size <= (TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block)+inter_frag)){
// printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2\n");
remove_block_from_free_list(head,&meta_data_block->prev_block->free_node);
meta_data_block->prev_block->block_size += req_rem_size;
req_rem_size -= inter_frag;
uint32_t final_remain = abs(TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block) - req_rem_size);
memcpy((char *)(meta_data_block->prev_block+1), (char *)(meta_data_block+1),meta_data_block->block_size);
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
end_meta_data_block->block_size = meta_data_block->block_size;
meta_data_block = meta_data_block->prev_block;
if( final_remain > META_DATA_OVERHEAD)
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1);
return (void *)(meta_data_block+1);
}
if(meta_data_block->next_block && meta_data_block->next_block->is_free && meta_data_block->prev_block && meta_data_block->prev_block->is_free && \
req_rem_size <= TOTAL_COMBINED_SIZE_OF_BLOCKS(meta_data_block)+inter_frag)
{
remove_block_from_free_list(head,&meta_data_block->prev_block->free_node);
remove_block_from_free_list(head,&meta_data_block->next_block->free_node);
// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11111\n");
// printf("%d %d %d %d[]block size]\n",meta_data_block->prev_block->block_size, meta_data_block->block_size , meta_data_block->next_block->block_size, req_rem_size);
req_rem_size = abs(meta_data_block->prev_block->block_size-size);
meta_data_block->prev_block->block_size += req_rem_size;
printf("%d \n", meta_data_block->prev_block->block_size);
req_rem_size -= inter_frag;
uint32_t final_remain = abs(meta_data_block->next_block->block_size+meta_data_block->prev_block->block_size+(uint32_t)sizeof(block_end_meta_data_t) \
+(uint32_t)sizeof(block_meta_data_t) - req_rem_size);
// printf("\n%d %d %d[REMAIN SIZE*********************************]\n",meta_data_block->next_block->block_size,meta_data_block->prev_block->block_size,final_remain);
memcpy((char *)(meta_data_block->prev_block+1), (char *)(meta_data_block+1),meta_data_block->block_size);
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
end_meta_data_block->block_size = meta_data_block->block_size;
meta_data_block = meta_data_block->prev_block;
if( final_remain > META_DATA_OVERHEAD)
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,0);
return (void *)(meta_data_block+1);
}
void *ptr = mm_malloc(size);
block_meta_data_t *new_meta_data_block = (block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t));
uint32_t amount_to_be_copied = meta_data_block->block_size;
memcpy((char *)(new_meta_data_block+1), (char *)(meta_data_block+1),amount_to_be_copied);
mm_free((void *)(meta_data_block+1));
return (void *)(new_meta_data_block+1);
}
}
......@@ -544,18 +762,32 @@ int main(int argc,char *argv[])
{
mm_init();
void *p1=mm_malloc(40);
int *p1=mm_malloc(50);
void *p2=mm_malloc(40);
void *p3=mm_malloc(40);
// int i=0;
// for(i =0;i<6;i++)
// p1[i] = i;
mm_free(p1);
void *p3=mm_malloc(70);
mm_free(p3);
void *p4 = mm_malloc(40);
// block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)p3-sizeof(block_meta_data_t));
// meta_data_block=(block_meta_data_t *)((char *)p2-sizeof(block_meta_data_t));
p1 = mm_realloc(p1,4000);
// for(int j=0;j<6;j++)
// printf("%d value\n",p1[j]);
mm_free(p4);
mm_free(p1);
mm_free(p2);
mm_free(p3);
mm_malloc(60);
......
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