Commit 5d3439c4 authored by Shivaji's avatar Shivaji

memory overwrite in mm2

parents 40a0fea0 b52f8bf7
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include<stddef.h>
#include<stdint.h>
#include "mm.h" #include "mm.h"
#include "memlib.h" #include "memlib.h"
...@@ -67,13 +69,22 @@ uint32_t block_size; ...@@ -67,13 +69,22 @@ uint32_t block_size;
} block_end_meta_data_t; } block_end_meta_data_t;
/* 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 NEXT_META_BLOCK(block_meta_data_ptr) \ #define NEXT_META_BLOCK(block_meta_data_ptr) \
(block_meta_data_ptr->next_block) (block_meta_data_ptr->next_block)
#define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \ #define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \
(block_meta_data_t *)((char *)(block_meta_data_ptr+1) \ (block_meta_data_t *)((char *)(block_meta_data_ptr)+ALIGN(sizeof(block_meta_data_t)) \
+ block_meta_data_ptr->block_size \ + block_meta_data_ptr->block_size \
+sizeof(block_end_meta_data_t)) +ALIGN(sizeof(block_end_meta_data_t)))
#define PREV_META_BLOCK(block_meta_data_ptr) \ #define PREV_META_BLOCK(block_meta_data_ptr) \
(block_meta_data_ptr->prev_block) (block_meta_data_ptr->prev_block)
...@@ -85,47 +96,35 @@ uint32_t block_size; ...@@ -85,47 +96,35 @@ uint32_t block_size;
if(free_meta_block->next_block) \ if(free_meta_block->next_block) \
free_meta_block->next_block->prev_block=free_meta_block free_meta_block->next_block->prev_block=free_meta_block
#define offsetof(struct_name,field_name) \
(unsigned int)&((struct_name *)0)->field_name
#define meta_data_block_addr(free_node_addr) \ #define meta_data_block_addr(free_node_addr) \
(block_meta_data_t *) ((char *)(free_node_addr)-offsetof(block_meta_data_t,free_node)) (block_meta_data_t *) ((char *)(free_node_addr)-offsetof(block_meta_data_t,free_node))
#define end_meta_data_addr(meta_data_addr) \ #define end_meta_data_addr(meta_data_addr) \
(block_end_meta_data_t *)((char *)(meta_data_addr+1) \ (block_end_meta_data_t *)((char *)(meta_data_addr)+ALIGN(sizeof(block_meta_data_t)) \
+meta_data_addr->block_size) +meta_data_addr->block_size)
#define start_meta_data_addr(end_meta_data_addr) \ #define start_meta_data_addr(end_meta_data_addr) \
(block_meta_data_t *)((char *)(end_meta_data_addr) \ (block_meta_data_t *)((char *)(end_meta_data_addr) \
-end_meta_data_addr->block_size \ -end_meta_data_addr->block_size \
-sizeof(block_meta_data_t)) -ALIGN(sizeof(block_meta_data_t)))
/* 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 TOTAL_COMBINE_SIZE_OF_BLOCKS(base) \ #define TOTAL_COMBINE_SIZE_OF_BLOCKS(base) \
base->block_size \ base->block_size \
+sizeof(block_end_meta_data_t) \ +ALIGN(sizeof(block_end_meta_data_t)) \
+sizeof(block_meta_data_t) +ALIGN(sizeof(block_meta_data_t))
#define TOTAL_COMBINED_SIZE_OF_BLOCKS(base) \ #define TOTAL_COMBINED_SIZE_OF_BLOCKS(base) \
base->next_block->block_size \ base->next_block->block_size \
+base->prev_block->block_size \ +base->prev_block->block_size \
+2*sizeof(block_end_meta_data_t) \ +2*ALIGN(sizeof(block_end_meta_data_t)) \
+2*sizeof(block_meta_data_t) +2*ALIGN(sizeof(block_meta_data_t))
#define META_DATA_OVERHEAD \ #define META_DATA_OVERHEAD \
(uint32_t)(sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t)) (uint32_t)(ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(block_meta_data_t)))
/* /*
* mm_init - initialize the malloc package. * mm_init - initialize the malloc package.
...@@ -232,7 +231,7 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second) ...@@ -232,7 +231,7 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second)
assert(first->is_free==MM_TRUE&&second->is_free==MM_TRUE); assert(first->is_free==MM_TRUE&&second->is_free==MM_TRUE);
first->block_size+=sizeof(block_meta_data_t) + second->block_size+sizeof(block_end_meta_data_t); first->block_size+=ALIGN(sizeof(block_meta_data_t)) + second->block_size+ALIGN(sizeof(block_end_meta_data_t));
first->next_block=second->next_block; first->next_block=second->next_block;
...@@ -277,8 +276,6 @@ void remove_block_from_free_list(free_node_t **head,free_node_t *del_node) ...@@ -277,8 +276,6 @@ void remove_block_from_free_list(free_node_t **head,free_node_t *del_node)
} }
del_node->prev_node=NULL; del_node->prev_node=NULL;
del_node->next_node=NULL; del_node->next_node=NULL;
free_node_t *head1=*head;
// while (head1) // while (head1)
// { // {
// block_meta_data_t *trace = (block_meta_data_t *)meta_data_block_addr(head1); // block_meta_data_t *trace = (block_meta_data_t *)meta_data_block_addr(head1);
...@@ -299,7 +296,7 @@ int get_internal_fragmented_size(block_meta_data_t *block1,block_meta_data_t *bl ...@@ -299,7 +296,7 @@ int get_internal_fragmented_size(block_meta_data_t *block1,block_meta_data_t *bl
void *allocate_requested_size(size_t size) void *allocate_requested_size(size_t size)
{ {
size_t sys_page_size=mem_pagesize(); 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); int no_of_pages_req=((size+ALIGN(sizeof(block_end_meta_data_t))+ALIGN(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; size_t extra_size_req=(int)no_of_pages_req*sys_page_size;
void *brk= mem_sbrk(extra_size_req); void *brk= mem_sbrk(extra_size_req);
if(*(int *)brk==-1) if(*(int *)brk==-1)
...@@ -309,7 +306,8 @@ void *allocate_requested_size(size_t size) ...@@ -309,7 +306,8 @@ void *allocate_requested_size(size_t size)
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) 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); 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;
// printf("%d[NEW BLOCK BEFORE SIZE]\n", new_block->block_size); // printf("%d[NEW BLOCK BEFORE SIZE]\n", new_block->block_size);
if(meta_data_block->is_free == MM_TRUE) if(meta_data_block->is_free == MM_TRUE)
meta_data_block->is_free = MM_FALSE; meta_data_block->is_free = MM_FALSE;
...@@ -317,6 +315,9 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc ...@@ -317,6 +315,9 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc
meta_data_block->next_block = free_block->next_block->next_block; meta_data_block->next_block = free_block->next_block->next_block;
else else
meta_data_block->next_block = free_block->next_block; meta_data_block->next_block = free_block->next_block;
if(final_remain <= META_DATA_OVERHEAD)
return;
block_meta_data_t *new_block = (block_meta_data_t *)NEXT_META_BLOCK_BY_SIZE(meta_data_block);
new_block->block_size = (uint32_t)final_remain; new_block->block_size = (uint32_t)final_remain;
new_block->free_node = init_free_node(); new_block->free_node = init_free_node();
new_block->is_free = MM_TRUE; new_block->is_free = MM_TRUE;
...@@ -324,6 +325,10 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc ...@@ -324,6 +325,10 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc
assert(meta_data_block->next_block->block_size == new_block->block_size); 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); 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; new_end_meta_data_block->block_size = new_block->block_size;
if(new_block->next_block && new_block->next_block->is_free == MM_TRUE)
merge_free_blocks(new_block, new_block->next_block);
if(new_block->prev_block && new_block->prev_block->is_free == MM_TRUE)
merge_free_blocks(new_block, new_block->prev_block);
insert_node_in_freelist(head,new_block); insert_node_in_freelist(head,new_block);
} }
...@@ -341,9 +346,9 @@ int mm_init(void) ...@@ -341,9 +346,9 @@ int mm_init(void)
return -1; return -1;
} }
head=(free_node_t **)init_mem_sbrk_break; head=(free_node_t **)init_mem_sbrk_break;
block_meta_data_t *metadata=(block_meta_data_t *)(head+1); block_meta_data_t *metadata=(block_meta_data_t *)((char *)head+ALIGN(sizeof(head)));
metadata->is_free=MM_TRUE; metadata->is_free=MM_TRUE;
metadata->block_size=mem_pagesize()-sizeof(block_meta_data_t)-sizeof(block_end_meta_data_t)-sizeof(head); metadata->block_size=mem_pagesize()-ALIGN(sizeof(block_meta_data_t))-ALIGN(sizeof(block_end_meta_data_t))-ALIGN(sizeof(head));
metadata->free_node=init_free_node(); metadata->free_node=init_free_node();
metadata->next_block=NULL; metadata->next_block=NULL;
metadata->prev_block=NULL; metadata->prev_block=NULL;
...@@ -378,7 +383,7 @@ void *mm_malloc(size_t size) ...@@ -378,7 +383,7 @@ void *mm_malloc(size_t size)
* Try to keep the heap size as small as possible. * Try to keep the heap size as small as possible.
*/ */
printf("[IN MALLOC]\n");
if(size <= 0){ // Invalid request size if(size <= 0){ // Invalid request size
return NULL; return NULL;
} }
...@@ -392,9 +397,14 @@ void *mm_malloc(size_t size) ...@@ -392,9 +397,14 @@ void *mm_malloc(size_t size)
void *brk = allocate_requested_size(size); void *brk = allocate_requested_size(size);
if(brk==NULL)
{
return brk;
}
block_end_meta_data_t *prev_end_meta_data=NULL; block_end_meta_data_t *prev_end_meta_data=NULL;
prev_end_meta_data=(block_end_meta_data_t *)((char *)brk-sizeof(block_end_meta_data_t)); prev_end_meta_data=(block_end_meta_data_t *)((char *)brk-ALIGN(sizeof(block_end_meta_data_t)));
block_meta_data_t *prev_start_meta_data=NULL; block_meta_data_t *prev_start_meta_data=NULL;
...@@ -424,7 +434,7 @@ void *mm_malloc(size_t size) ...@@ -424,7 +434,7 @@ void *mm_malloc(size_t size)
// 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->block_size= (uint32_t)((char *)mem_heap_hi()-(char *)brk+1-size-(2*(uint32_t)ALIGN(sizeof(block_meta_data_t)))-(2*(uint32_t)ALIGN(sizeof(block_end_meta_data_t))));
new_free_meta_block->free_node=init_free_node(); new_free_meta_block->free_node=init_free_node();
...@@ -438,12 +448,12 @@ void *mm_malloc(size_t size) ...@@ -438,12 +448,12 @@ void *mm_malloc(size_t size)
mm_bind_blocks_for_allocation(next_meta_data_block,new_free_meta_block); mm_bind_blocks_for_allocation(next_meta_data_block,new_free_meta_block);
return (void *)(next_meta_data_block+1); return (void *)((char *)next_meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
assert(free_metadata_block->is_free==MM_TRUE); assert(free_metadata_block->is_free==MM_TRUE);
printf("Free Data block size=%d\n",(int)free_metadata_block->block_size); //printf("Free Data block size=%d\n",(int)free_metadata_block->block_size);
uint32_t remaining_size=free_metadata_block->block_size-size; uint32_t remaining_size=free_metadata_block->block_size-size;
...@@ -458,18 +468,17 @@ void *mm_malloc(size_t size) ...@@ -458,18 +468,17 @@ void *mm_malloc(size_t size)
remove_block_from_free_list(head,&free_metadata_block->free_node); remove_block_from_free_list(head,&free_metadata_block->free_node);
//Here we will created new block by splitting previous block //Here we will created new block by splitting previous block
if(sizeof(block_meta_data_t)+sizeof(block_end_meta_data_t)<remaining_size){ if(ALIGN(sizeof(block_meta_data_t))+ALIGN(sizeof(block_end_meta_data_t))<remaining_size){
block_meta_data_t *next_meta_block=NULL; block_meta_data_t *next_meta_block=NULL;
block_end_meta_data_t *next_end_meta_block=NULL; 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=NEXT_META_BLOCK_BY_SIZE(free_metadata_block);
next_meta_block->is_free=MM_TRUE; next_meta_block->is_free=MM_TRUE;
next_meta_block->block_size=remaining_size-sizeof(block_meta_data_t)-sizeof(block_end_meta_data_t); next_meta_block->block_size=remaining_size-ALIGN(sizeof(block_meta_data_t))-ALIGN(sizeof(block_end_meta_data_t));
next_meta_block->free_node=init_free_node(); next_meta_block->free_node=init_free_node();
...@@ -487,7 +496,7 @@ void *mm_malloc(size_t size) ...@@ -487,7 +496,7 @@ void *mm_malloc(size_t size)
return (void *)(free_metadata_block+1); return (void *)((char *)free_metadata_block+ALIGN(sizeof(block_meta_data_t)));
//mem_sbrk() is wrapper function for the sbrk() system call. //mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results //Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
...@@ -509,7 +518,8 @@ void mm_free(void *ptr) ...@@ -509,7 +518,8 @@ void mm_free(void *ptr)
* If the freed block is at the end of the heap then you can also decrease the heap size * If the freed block is at the end of the heap then you can also decrease the heap size
* using 'mem_sbrk(-size)'. * using 'mem_sbrk(-size)'.
*/ */
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t)); printf("[IN FREE]\n");
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-ALIGN(sizeof(block_meta_data_t)));
assert(meta_data_block->is_free==MM_FALSE); assert(meta_data_block->is_free==MM_FALSE);
...@@ -531,7 +541,7 @@ void mm_free(void *ptr) ...@@ -531,7 +541,7 @@ void mm_free(void *ptr)
//If block being free is upper most block //If block being free is upper most block
else else
{ {
int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t))); int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+ALIGN(sizeof(block_end_meta_data_t))));
meta_data_block->block_size+=fragmented_size; meta_data_block->block_size+=fragmented_size;
} }
...@@ -560,7 +570,6 @@ void mm_free(void *ptr) ...@@ -560,7 +570,6 @@ void mm_free(void *ptr)
merged_end_meta_data_block->block_size=merged_meta_data_block->block_size; 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); insert_node_in_freelist(head,merged_meta_data_block);
} }
...@@ -582,7 +591,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -582,7 +591,7 @@ void *mm_realloc(void *ptr, size_t size)
// mm_free(ptr); // mm_free(ptr);
// return mem_sbrk(size); // return mem_sbrk(size);
printf("[IN REALLOC]\n");
size = ((size+7)/8)*8; //8-byte alignement size = ((size+7)/8)*8; //8-byte alignement
// printf("%lu [SIZE AFTER ALIGNMNET]",size); // printf("%lu [SIZE AFTER ALIGNMNET]",size);
...@@ -596,14 +605,14 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -596,14 +605,14 @@ void *mm_realloc(void *ptr, size_t size)
return NULL; return NULL;
} }
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t)); block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-ALIGN(sizeof(block_meta_data_t)));
if(size == meta_data_block->block_size) if(size == meta_data_block->block_size)
return (void *)(meta_data_block+1); return meta_data_block;
// if provided size is less than already allocated size `if block` will be executed otherwiae `else 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) if(size < meta_data_block->block_size)
{ {
uint32_t original_size = (uint32_t)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); uint32_t inter_frag = (uint32_t)get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
...@@ -614,9 +623,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -614,9 +623,7 @@ void *mm_realloc(void *ptr, size_t size)
{ {
block_meta_data_t *new_block = NEXT_META_BLOCK_BY_SIZE(meta_data_block); 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); 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); 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);
meta_data_block->next_block = meta_data_block->next_block->next_block; meta_data_block->next_block = meta_data_block->next_block->next_block;
new_block->is_free = MM_TRUE; new_block->is_free = MM_TRUE;
new_block->free_node= init_free_node(); new_block->free_node= init_free_node();
...@@ -626,21 +633,20 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -626,21 +633,20 @@ void *mm_realloc(void *ptr, size_t size)
new_end_meta_data_block->block_size = new_block->block_size; new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(head,new_block); 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 *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
return (void *)(meta_data_block+1);
} }
else else
{ {
uint32_t inter_frag =0; 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))); int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+ALIGN(sizeof(block_end_meta_data_t))));
if(!meta_data_block->next_block){ if(!meta_data_block->next_block){
if( (fragmented_size+original_size-size) < (sizeof(block_end_meta_data_t)+sizeof(end_meta_data_block)) ) if( (fragmented_size+original_size-size) < (ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(end_meta_data_block))) )
return meta_data_block; return meta_data_block;
} }
else{ else{
uint32_t inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block); 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)) ) if( (inter_frag+original_size-size) < (ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(end_meta_data_block))) )
return meta_data_block; return meta_data_block;
fragmented_size = 0; fragmented_size = 0;
} }
...@@ -660,7 +666,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -660,7 +666,7 @@ void *mm_realloc(void *ptr, size_t size)
new_end_meta_data_block->block_size = new_block->block_size; new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(head,new_block); insert_node_in_freelist(head,new_block);
} }
return (void *)(meta_data_block+1); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
} }
else else
...@@ -670,7 +676,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -670,7 +676,7 @@ void *mm_realloc(void *ptr, size_t size)
if(meta_data_block->next_block) if(meta_data_block->next_block)
inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block); inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
else else
inter_frag = (uint32_t)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t))); inter_frag = (uint32_t)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+ALIGN(sizeof(block_end_meta_data_t))));
if(req_rem_size <= inter_frag) if(req_rem_size <= inter_frag)
{ {
...@@ -679,7 +685,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -679,7 +685,7 @@ void *mm_realloc(void *ptr, size_t size)
block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block); 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; 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. return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t))); // Not handling adding remaining free part to free list because it is small in size to handle even headers, so skkipping.
} }
...@@ -688,19 +694,14 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -688,19 +694,14 @@ void *mm_realloc(void *ptr, size_t size)
{ {
// printf("%p [IN REALLAOC]\n",&meta_data_block->next_block->free_node); // 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); 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 = size;
meta_data_block->block_size += req_rem_size;
req_rem_size -= inter_frag; req_rem_size -= inter_frag;
// printf("%d [FINAL REMAINING] %d [ALLTED BLOCK SIZE]\n",final_remain, meta_data_block->block_size); uint32_t final_remain = TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->next_block) - req_rem_size;
// printf("%d [SIZE TO REMOVED FROM FREE LIST]\n", meta_data_block->next_block->block_size); // block_end_meta_data_t *end_meta_data_block = (block_end_meta_data_t *)end_meta_data_addr(meta_data_block);
// printf("[REMOVED$$$$$$$$$$$$$$$$$]\n"); // end_meta_data_block->block_size = 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; create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1);
if( final_remain > META_DATA_OVERHEAD) return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
{
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1);
}
return (void *)(meta_data_block+1);
} }
...@@ -708,16 +709,15 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -708,16 +709,15 @@ void *mm_realloc(void *ptr, size_t size)
req_rem_size <= (TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block)+inter_frag)){ req_rem_size <= (TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block)+inter_frag)){
// printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2\n"); // printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2\n");
remove_block_from_free_list(head,&meta_data_block->prev_block->free_node); remove_block_from_free_list(head,&meta_data_block->prev_block->free_node);
meta_data_block->prev_block->block_size += req_rem_size; meta_data_block->prev_block->block_size = size;
req_rem_size -= inter_frag; req_rem_size -= inter_frag;
uint32_t final_remain = abs(TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block) - req_rem_size); 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); memcpy((char *)(meta_data_block->prev_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),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); // 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; // end_meta_data_block->block_size = meta_data_block->block_size;
meta_data_block = meta_data_block->prev_block; 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);
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
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 && \ 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 && \
...@@ -726,73 +726,101 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -726,73 +726,101 @@ void *mm_realloc(void *ptr, size_t size)
remove_block_from_free_list(head,&meta_data_block->prev_block->free_node); 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); remove_block_from_free_list(head,&meta_data_block->next_block->free_node);
// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11111\n"); // 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); req_rem_size = abs(meta_data_block->prev_block->block_size-size);
meta_data_block->prev_block->block_size += req_rem_size; meta_data_block->prev_block->block_size = size;
printf("%d \n", meta_data_block->prev_block->block_size);
req_rem_size -= inter_frag; 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 final_remain = abs(meta_data_block->next_block->block_size+meta_data_block->prev_block->block_size+(uint32_t)ALIGN(sizeof(block_end_meta_data_t)) \
+(uint32_t)sizeof(block_meta_data_t) - req_rem_size); +(uint32_t)ALIGN(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)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),meta_data_block->block_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);
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;
end_meta_data_block->block_size = meta_data_block->block_size;
meta_data_block = meta_data_block->prev_block; 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);
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,0); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
return (void *)(meta_data_block+1);
} }
void *ptr = mm_malloc(size); void *ptr = mm_malloc(size);
block_meta_data_t *new_meta_data_block = (block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t)); block_meta_data_t *new_meta_data_block = (block_meta_data_t *)((char *)ptr-ALIGN(sizeof(block_meta_data_t)));
uint32_t amount_to_be_copied = meta_data_block->block_size; 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); memcpy((char *)(new_meta_data_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),amount_to_be_copied);
mm_free((void *)(meta_data_block+1)); mm_free((void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t))));
return (void *)(new_meta_data_block+1); return (void *)((char *)new_meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
} }
int main(int argc,char *argv[]) void traverse_list(free_node_t *root)
{ {
mm_init(); while(root!=NULL)
{
block_meta_data_t *meta_data=meta_data_block_addr(root);
int *p1=mm_malloc(400); printf("Block size =%d\n",meta_data->block_size);
void *p2=mm_malloc(400); root=root->next_node;
}
// int i=0; }
// for(i =0;i<6;i++)
// p1[i] = i;
void *p3=mm_malloc(400);
void *p4 = mm_malloc(400); // int main(int argc,char *argv[])
// 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)); // mm_init();
mm_malloc(60); // int *p1=mm_malloc(400);
// for(int j=0;j<6;j++)
// printf("%d value\n",p1[j]);
mm_free(p2); // void *p2=mm_malloc(400);
mm_free(p4); // // int i=0;
// // for(i =0;i<6;i++)
// // p1[i] = i;
p1 = mm_realloc(p1,300); // void *p3=mm_malloc(400);
mm_free(p1); // void *p4 = mm_malloc(400);
// // 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));
mm_free(p3); // p4 = mm_realloc(p4,3904);
mm_malloc(100); // p1 = mm_realloc(p1,1000);
return 0; // p2 = mm_realloc(p2,1000);
// p3 = mm_realloc(p3,100000);
} // //void *p5=mm_malloc(60);
// // for(int j=0;j<6;j++)
// // printf("%d value\n",p1[j]);
// mm_free(p4);
// // void *p3=mm_malloc(400);
// traverse_list(*head);
// // mm_free(p2);
// printf("%d \n",(unsigned int)mem_heap_hi()-(unsigned int)mem_heap_lo());
// // traverse_list(*head);
// // mm_free(p4);
// // mm_free(p3);
// //mm_free(p5);
// mm_malloc(100);
// mm_malloc(100);
// return 0;
// }
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include<stddef.h>
#include<stdint.h>
#include "mm.h" #include "mm.h"
#include "memlib.h" #include "memlib.h"
...@@ -73,9 +75,9 @@ uint32_t block_size; ...@@ -73,9 +75,9 @@ uint32_t block_size;
#define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \ #define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \
(block_meta_data_t *)((char *)(block_meta_data_ptr+1) \ (block_meta_data_t *)((char *)(block_meta_data_ptr)+ALIGN(sizeof(block_meta_data_t)) \
+ block_meta_data_ptr->block_size \ + block_meta_data_ptr->block_size \
+sizeof(block_end_meta_data_t)) +ALIGN(sizeof(block_end_meta_data_t)))
#define mm_bind_blocks_for_allocation(allocated_meta_block,free_meta_block) \ #define mm_bind_blocks_for_allocation(allocated_meta_block,free_meta_block) \
free_meta_block->prev_block=allocated_meta_block; \ free_meta_block->prev_block=allocated_meta_block; \
...@@ -92,27 +94,29 @@ uint32_t block_size; ...@@ -92,27 +94,29 @@ uint32_t block_size;
(block_meta_data_t *) ((char *)(free_node_addr)-offsetof(block_meta_data_t,tree_node)) (block_meta_data_t *) ((char *)(free_node_addr)-offsetof(block_meta_data_t,tree_node))
#define end_meta_data_addr(meta_data_addr) \ #define end_meta_data_addr(meta_data_addr) \
(block_end_meta_data_t *)((char *)(meta_data_addr+1) \ (block_end_meta_data_t *)((char *)(meta_data_addr)+ALIGN(sizeof(block_meta_data_t)) \
+meta_data_addr->block_size) +meta_data_addr->block_size)
#define start_meta_data_addr(end_meta_data_addr) \ #define start_meta_data_addr(end_meta_data_addr) \
(block_meta_data_t *)((char *)(end_meta_data_addr) \ (block_meta_data_t *)((char *)(end_meta_data_addr) \
-end_meta_data_addr->block_size \ -end_meta_data_addr->block_size \
-sizeof(block_meta_data_t)) -ALIGN(sizeof(block_meta_data_t)))
#define META_DATA_OVERHEAD \ #define META_DATA_OVERHEAD \
(uint32_t)(sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t)) (uint32_t)(ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(block_meta_data_t)))
#define TOTAL_COMBINE_SIZE_OF_BLOCKS(base) \ #define TOTAL_COMBINE_SIZE_OF_BLOCKS(base) \
base->block_size \ base->block_size \
+sizeof(block_end_meta_data_t) \ +ALIGN(sizeof(block_end_meta_data_t)) \
+sizeof(block_meta_data_t) +ALIGN(sizeof(block_meta_data_t))
#define TOTAL_COMBINED_SIZE_OF_BLOCKS(base) \ #define TOTAL_COMBINED_SIZE_OF_BLOCKS(base) \
base->next_block->block_size \ base->next_block->block_size \
+base->prev_block->block_size \ +base->prev_block->block_size \
+2*sizeof(block_end_meta_data_t) \ +2*ALIGN(sizeof(block_end_meta_data_t)) \
+2*sizeof(block_meta_data_t) +2*ALIGN(sizeof(block_meta_data_t))
/* single word (4) or double word (8) alignment */ /* single word (4) or double word (8) alignment */
#define ALIGNMENT 8 #define ALIGNMENT 8
...@@ -674,7 +678,7 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second) ...@@ -674,7 +678,7 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second)
assert(first->is_free==MM_TRUE&&second->is_free==MM_TRUE); assert(first->is_free==MM_TRUE&&second->is_free==MM_TRUE);
first->block_size+=sizeof(block_meta_data_t) + second->block_size+sizeof(block_end_meta_data_t); first->block_size+=ALIGN(sizeof(block_meta_data_t)) + second->block_size+ALIGN(sizeof(block_end_meta_data_t));
first->next_block=second->next_block; first->next_block=second->next_block;
...@@ -688,6 +692,8 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second) ...@@ -688,6 +692,8 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second)
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) 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_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;
block_meta_data_t *new_block = (block_meta_data_t *)NEXT_META_BLOCK_BY_SIZE(meta_data_block); block_meta_data_t *new_block = (block_meta_data_t *)NEXT_META_BLOCK_BY_SIZE(meta_data_block);
if(meta_data_block->is_free == MM_TRUE) if(meta_data_block->is_free == MM_TRUE)
meta_data_block->is_free = MM_FALSE; meta_data_block->is_free = MM_FALSE;
...@@ -702,6 +708,10 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc ...@@ -702,6 +708,10 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc
assert(meta_data_block->next_block->block_size == new_block->block_size); 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); 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; new_end_meta_data_block->block_size = new_block->block_size;
// if(new_block->next_block && new_block->next_block->is_free == MM_TRUE)
// merge_free_blocks(new_block, new_block->next_block);
// if(new_block->prev_block && new_block->prev_block->is_free == MM_TRUE)
// merge_free_blocks(new_block, new_block->prev_block);
insert_node_in_freelist(root,new_block); insert_node_in_freelist(root,new_block);
} }
...@@ -709,7 +719,7 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc ...@@ -709,7 +719,7 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc
void *allocate_requested_size(size_t size) void *allocate_requested_size(size_t size)
{ {
size_t sys_page_size=mem_pagesize(); 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); int no_of_pages_req=((size+ALIGN(sizeof(block_end_meta_data_t))+ALIGN(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; size_t extra_size_req=(int)no_of_pages_req*sys_page_size;
void *brk= mem_sbrk(extra_size_req); void *brk= mem_sbrk(extra_size_req);
if(*(int *)brk==-1) if(*(int *)brk==-1)
...@@ -742,9 +752,9 @@ int mm_init(void) ...@@ -742,9 +752,9 @@ int mm_init(void)
return -1; return -1;
} }
root=(tree_node_t **)init_mem_sbrk_break; root=(tree_node_t **)init_mem_sbrk_break;
block_meta_data_t *metadata=(block_meta_data_t *)(root+1); block_meta_data_t *metadata=(block_meta_data_t *)((char *)root+ALIGN(sizeof(root)));
metadata->is_free=MM_TRUE; metadata->is_free=MM_TRUE;
metadata->block_size=mem_pagesize()-sizeof(block_meta_data_t)-sizeof(block_end_meta_data_t)-sizeof(root); metadata->block_size=mem_pagesize()-ALIGN(sizeof(block_meta_data_t))-ALIGN(sizeof(block_end_meta_data_t))-ALIGN(sizeof(root));
metadata->tree_node=init_free_node(); metadata->tree_node=init_free_node();
metadata->next_block=NULL; metadata->next_block=NULL;
metadata->prev_block=NULL; metadata->prev_block=NULL;
...@@ -768,7 +778,7 @@ void *mm_malloc(size_t size) ...@@ -768,7 +778,7 @@ void *mm_malloc(size_t size)
* If no appropriate free block is available then the increase the heap size using 'mem_sbrk(size)'. * 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. * Try to keep the heap size as small as possible.
*/ */
printf("[IN MALLOC]\n");
if(size <= 0){ // Invalid request size if(size <= 0){ // Invalid request size
return NULL; return NULL;
} }
...@@ -777,14 +787,19 @@ void *mm_malloc(size_t size) ...@@ -777,14 +787,19 @@ void *mm_malloc(size_t size)
block_meta_data_t *free_metadata_block=get_node_from_tree(root,size); block_meta_data_t *free_metadata_block=get_node_from_tree(root,size);
//If No free block available then we will request new pages by calling mem_sbrk() //If No free block available then we will request new pages by calling mem_sbrk()
if(free_metadata_block==NULL||free_metadata_block->block_size<(size+sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t))) if(free_metadata_block==NULL||free_metadata_block->block_size<(size+ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(block_meta_data_t))))
{ {
void *brk = allocate_requested_size(size); void *brk = allocate_requested_size(size);
if(brk==NULL)
{
return NULL;
}
block_end_meta_data_t *prev_end_meta_data=NULL; block_end_meta_data_t *prev_end_meta_data=NULL;
prev_end_meta_data=(block_end_meta_data_t *)((char *)brk-sizeof(block_end_meta_data_t)); prev_end_meta_data=(block_end_meta_data_t *)((char *)brk-ALIGN(sizeof(block_end_meta_data_t)));
block_meta_data_t *prev_start_meta_data=NULL; block_meta_data_t *prev_start_meta_data=NULL;
...@@ -813,7 +828,7 @@ void *mm_malloc(size_t size) ...@@ -813,7 +828,7 @@ void *mm_malloc(size_t size)
new_free_meta_block->is_free=MM_TRUE; 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->block_size= (uint32_t)((char *)mem_heap_hi()-(char *)brk+1-size-(2*(uint32_t)ALIGN(sizeof(block_meta_data_t)))-(2*(uint32_t)ALIGN(sizeof(block_end_meta_data_t))));
new_free_meta_block->tree_node=init_free_node(); new_free_meta_block->tree_node=init_free_node();
...@@ -827,7 +842,7 @@ void *mm_malloc(size_t size) ...@@ -827,7 +842,7 @@ void *mm_malloc(size_t size)
mm_bind_blocks_for_allocation(next_meta_data_block,new_free_meta_block); mm_bind_blocks_for_allocation(next_meta_data_block,new_free_meta_block);
return (void *)(next_meta_data_block+1); return (void *)((char *)next_meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
assert(free_metadata_block->is_free==MM_TRUE); assert(free_metadata_block->is_free==MM_TRUE);
...@@ -847,7 +862,7 @@ void *mm_malloc(size_t size) ...@@ -847,7 +862,7 @@ void *mm_malloc(size_t size)
remove_block_from_tree(root,&free_metadata_block->tree_node); remove_block_from_tree(root,&free_metadata_block->tree_node);
//Here we will created new block by splitting previous block //Here we will created new block by splitting previous block
if(sizeof(block_meta_data_t)+sizeof(block_end_meta_data_t)<remaining_size){ if(ALIGN(sizeof(block_meta_data_t))+ALIGN(sizeof(block_end_meta_data_t))<remaining_size){
block_meta_data_t *next_meta_block=NULL; block_meta_data_t *next_meta_block=NULL;
...@@ -857,7 +872,7 @@ void *mm_malloc(size_t size) ...@@ -857,7 +872,7 @@ void *mm_malloc(size_t size)
next_meta_block->is_free=MM_TRUE; next_meta_block->is_free=MM_TRUE;
next_meta_block->block_size=remaining_size-sizeof(block_meta_data_t)-sizeof(block_end_meta_data_t); next_meta_block->block_size=remaining_size-ALIGN(sizeof(block_meta_data_t))-ALIGN(sizeof(block_end_meta_data_t));
next_meta_block->tree_node=init_free_node(); next_meta_block->tree_node=init_free_node();
...@@ -872,7 +887,7 @@ void *mm_malloc(size_t size) ...@@ -872,7 +887,7 @@ void *mm_malloc(size_t size)
return (void *)(free_metadata_block+1); return (void *)((char *)free_metadata_block+ALIGN(sizeof(block_meta_data_t)));
//mem_sbrk() is wrapper function for the sbrk() system call. //mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results //Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
...@@ -892,8 +907,8 @@ void mm_free(void *ptr) ...@@ -892,8 +907,8 @@ void mm_free(void *ptr)
* If the freed block is at the end of the heap then you can also decrease the heap size * If the freed block is at the end of the heap then you can also decrease the heap size
* using 'mem_sbrk(-size)'. * using 'mem_sbrk(-size)'.
*/ */
printf("[IN FREE]\n");
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t)); block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-ALIGN(sizeof(block_meta_data_t)));
assert(meta_data_block->is_free==MM_FALSE); assert(meta_data_block->is_free==MM_FALSE);
...@@ -915,7 +930,7 @@ void mm_free(void *ptr) ...@@ -915,7 +930,7 @@ void mm_free(void *ptr)
//If block being free is upper most block //If block being free is upper most block
else else
{ {
int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t))); int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+ALIGN(sizeof(block_end_meta_data_t))));
meta_data_block->block_size+=fragmented_size; meta_data_block->block_size+=fragmented_size;
} }
...@@ -953,6 +968,7 @@ void mm_free(void *ptr) ...@@ -953,6 +968,7 @@ void mm_free(void *ptr)
*/ */
void *mm_realloc(void *ptr, size_t size) void *mm_realloc(void *ptr, size_t size)
{ {
printf("[IN REALLOC]\n");
size = ((size+7)/8)*8; //8-byte alignement size = ((size+7)/8)*8; //8-byte alignement
if(ptr == NULL){ //memory was not previously allocated if(ptr == NULL){ //memory was not previously allocated
...@@ -964,7 +980,6 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -964,7 +980,6 @@ void *mm_realloc(void *ptr, size_t size)
return NULL; return NULL;
} }
/* /*
* This function should also copy the content of the previous memory block into the new block. * This function should also copy the content of the previous memory block into the new block.
...@@ -974,13 +989,13 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -974,13 +989,13 @@ void *mm_realloc(void *ptr, size_t size)
* blocks should also be updated. * blocks should also be updated.
*/ */
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t)); block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-ALIGN(sizeof(block_meta_data_t)));
if(size == meta_data_block->block_size) if(size == meta_data_block->block_size)
return (void *)(meta_data_block+1); return (void *)(meta_data_block+1);
if(size < meta_data_block->block_size) if(size < meta_data_block->block_size)
{ {
uint32_t original_size = (uint32_t)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); uint32_t inter_frag = (uint32_t)get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
...@@ -1001,20 +1016,20 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -1001,20 +1016,20 @@ void *mm_realloc(void *ptr, size_t size)
new_end_meta_data_block->block_size = new_block->block_size; new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(root,new_block); insert_node_in_freelist(root,new_block);
return (void *)(meta_data_block+1); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
else else
{ {
uint32_t inter_frag =0; 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))); int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+ALIGN(sizeof(block_end_meta_data_t))));
if(!meta_data_block->next_block){ if(!meta_data_block->next_block){
if( (fragmented_size+original_size-size) < (sizeof(block_end_meta_data_t)+sizeof(end_meta_data_block)) ) if( (fragmented_size+original_size-size) < (ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(end_meta_data_block))) )
return meta_data_block; return meta_data_block;
} }
else{ else{
uint32_t inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block); 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)) ) if( (inter_frag+original_size-size) < (ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(end_meta_data_block))) )
return meta_data_block; return meta_data_block;
fragmented_size = 0; fragmented_size = 0;
} }
...@@ -1034,7 +1049,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -1034,7 +1049,7 @@ void *mm_realloc(void *ptr, size_t size)
new_end_meta_data_block->block_size = new_block->block_size; new_end_meta_data_block->block_size = new_block->block_size;
insert_node_in_freelist(root,new_block); insert_node_in_freelist(root,new_block);
} }
return (void *)(meta_data_block+1); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
} }
else else
...@@ -1044,49 +1059,31 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -1044,49 +1059,31 @@ void *mm_realloc(void *ptr, size_t size)
if(meta_data_block->next_block) if(meta_data_block->next_block)
inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block); inter_frag = get_internal_fragmented_size(meta_data_block,meta_data_block->next_block);
else else
inter_frag = (uint32_t)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t))); inter_frag = (uint32_t)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+ALIGN(sizeof(block_end_meta_data_t))));
if(req_rem_size <= inter_frag) if(req_rem_size <= inter_frag)
{ {
// TODO check sizeof function once // TODO check sizeof function once
meta_data_block->block_size += req_rem_size; 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); 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; 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. return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t))); // 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))
{
remove_block_from_tree(root,&meta_data_block->next_block->tree_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;
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 && \ 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)){ req_rem_size <= (TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block)+inter_frag)){
remove_block_from_tree(root,&meta_data_block->prev_block->tree_node); remove_block_from_tree(root,&meta_data_block->prev_block->tree_node);
meta_data_block->prev_block->block_size += req_rem_size;
req_rem_size -= inter_frag; req_rem_size -= inter_frag;
meta_data_block->prev_block->block_size = size;
uint32_t final_remain = abs(TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->prev_block) - req_rem_size); 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); memcpy((char *)(meta_data_block->prev_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),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); 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; end_meta_data_block->block_size = meta_data_block->block_size;
meta_data_block = meta_data_block->prev_block; 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);
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
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 && \ 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 && \
...@@ -1094,60 +1091,67 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -1094,60 +1091,67 @@ void *mm_realloc(void *ptr, size_t size)
{ {
remove_block_from_tree(root,&meta_data_block->prev_block->tree_node); remove_block_from_tree(root,&meta_data_block->prev_block->tree_node);
remove_block_from_tree(root,&meta_data_block->next_block->tree_node); remove_block_from_tree(root,&meta_data_block->next_block->tree_node);
req_rem_size = abs(meta_data_block->prev_block->block_size-size);
meta_data_block->prev_block->block_size += req_rem_size;
req_rem_size -= inter_frag; 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) \ meta_data_block->prev_block->block_size = size;
+(uint32_t)sizeof(block_meta_data_t) - req_rem_size); uint32_t final_remain = abs(meta_data_block->next_block->block_size+meta_data_block->prev_block->block_size+(uint32_t)ALIGN(sizeof(block_end_meta_data_t)) \
+(uint32_t)ALIGN(sizeof(block_meta_data_t)) - req_rem_size);
memcpy((char *)(meta_data_block->prev_block+1), (char *)(meta_data_block+1),meta_data_block->block_size); memcpy((char *)(meta_data_block->prev_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),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); 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; end_meta_data_block->block_size = meta_data_block->block_size;
meta_data_block = meta_data_block->prev_block; 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);
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,0); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
return (void *)(meta_data_block+1);
} }
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))
{
remove_block_from_tree(root,&meta_data_block->next_block->tree_node);
req_rem_size -= inter_frag;
uint32_t final_remain = TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->next_block) - req_rem_size;
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;
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1);
return (void *)(meta_data_block+1);
}
void *ptr = mm_malloc(size); void *ptr = mm_malloc(size);
block_meta_data_t *new_meta_data_block = (block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t)); block_meta_data_t *new_meta_data_block = (block_meta_data_t *)((char *)ptr-ALIGN(sizeof(block_meta_data_t)));
uint32_t amount_to_be_copied = meta_data_block->block_size; 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); memcpy((char *)(new_meta_data_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),amount_to_be_copied);
mm_free((void *)(meta_data_block+1)); mm_free((void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t))));
return (void *)(new_meta_data_block+1); return (void *)((char *)new_meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
mm_free(ptr);
return mem_sbrk(size);
} }
int main() // int main()
{ // {
mm_init(); // mm_init();
void *p1=mm_malloc(40); // void *p1=mm_malloc(40);
void *p3=mm_malloc(60); // void *p3=mm_malloc(60);
void *p4=mm_malloc(100); // void *p4=mm_malloc(100);
void *p5=mm_malloc(20); // void *p5=mm_malloc(20);
void *p6=mm_malloc(90); // void *p6=mm_malloc(90);
void *p7=mm_malloc(3500); // void *p7=mm_malloc(3500);
printf("Above Call Executed\n"); // printf("Above Call Executed\n");
// mm_free(p2); // // mm_free(p2);
mm_free(p4); // mm_free(p4);
mm_free(p6); // mm_free(p6);
mm_free(p1); // mm_free(p1);
// mm_free(p3); // // mm_free(p3);
// mm_free(p5); // // mm_free(p5);
// mm_free(p7); // // mm_free(p7);
printf("[FINAL INORDER TRAVERSAL]\n"); // printf("[FINAL INORDER TRAVERSAL]\n");
inorderTraversal(*root); // inorderTraversal(*root);
//mm_free(p2); // //mm_free(p2);
//mm_free(p2); // //mm_free(p2);
//void *p4=mm_malloc(40); // //void *p4=mm_malloc(40);
return 0; // return 0;
} // }
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