Commit 65e0c47a authored by Vadapalli K Chaitanya's avatar Vadapalli K Chaitanya

Update mm2.c

parent 45bbc0d8
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <string.h> #include <string.h>
#include<stddef.h> #include<stddef.h>
#include<stdint.h> #include<stdint.h>
#include "mm.h" #include "mm.h"
#include "memlib.h" #include "memlib.h"
...@@ -73,6 +72,9 @@ uint32_t block_size; ...@@ -73,6 +72,9 @@ uint32_t block_size;
} block_end_meta_data_t; } block_end_meta_data_t;
int c=0;
int m=0;
#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)+ALIGN(sizeof(block_meta_data_t)) \ (block_meta_data_t *)((char *)(block_meta_data_ptr)+ALIGN(sizeof(block_meta_data_t)) \
...@@ -143,10 +145,13 @@ void *init_mem_sbrk_break = NULL; ...@@ -143,10 +145,13 @@ void *init_mem_sbrk_break = NULL;
tree_node_t **root=NULL; tree_node_t **root=NULL;
void LL_rotate(tree_node_t *parent,tree_node_t *node) void LL_rotate(tree_node_t *parent,tree_node_t *node)
{ {
printf("Came to LL\n"); // printf("Came to LL\n");
tree_node_t *p_parent=parent->parent_node; tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->left_node; tree_node_t *temp=parent->left_node;
...@@ -162,17 +167,13 @@ void LL_rotate(tree_node_t *parent,tree_node_t *node) ...@@ -162,17 +167,13 @@ void LL_rotate(tree_node_t *parent,tree_node_t *node)
else else
{ {
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
temp->parent_node=p_parent; temp->parent_node=p_parent;
if(temp_meta_data->block_size<=p_parent_meta_data->block_size) if(p_parent->left_node==parent)
{ {
p_parent->left_node=temp; p_parent->left_node=temp;
} }
else else if(p_parent->right_node==parent)
{ {
p_parent->right_node=temp; p_parent->right_node=temp;
} }
...@@ -184,22 +185,26 @@ void LL_rotate(tree_node_t *parent,tree_node_t *node) ...@@ -184,22 +185,26 @@ void LL_rotate(tree_node_t *parent,tree_node_t *node)
parent->parent_node=temp; parent->parent_node=temp;
parent->left_node=temp_right; parent->left_node=temp_right;
if(temp_right!=NULL)
{
temp_right->parent_node=parent;
}
} }
void LR_Rotate(tree_node_t *parent,tree_node_t *node) void LR_Rotate(tree_node_t *parent,tree_node_t *node)
{ {
printf("Came to LR\n"); // printf("Came to LR\n");
tree_node_t *p_parent=parent->parent_node; tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->left_node; tree_node_t *temp=parent->left_node;
block_meta_data_t *meta_data=meta_data_block_addr(temp);
tree_node_t *node_left=node->left_node; tree_node_t *node_left=node->left_node;
tree_node_t *node_right=node->right_node; tree_node_t *node_right=node->right_node;
if(p_parent==NULL) if(p_parent==NULL)
{ {
*root=node; *root=node;
...@@ -208,15 +213,12 @@ void LR_Rotate(tree_node_t *parent,tree_node_t *node) ...@@ -208,15 +213,12 @@ void LR_Rotate(tree_node_t *parent,tree_node_t *node)
else else
{ {
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *node_meta_data=meta_data_block_addr(node);
node->parent_node=p_parent; node->parent_node=p_parent;
if(node_meta_data->block_size<=p_parent_meta_data->block_size) if(p_parent->left_node==parent)
{ {
p_parent->left_node=node; p_parent->left_node=node;
} }
else else if(p_parent->right_node==parent)
{ {
p_parent->right_node=node; p_parent->right_node=node;
} }
...@@ -227,17 +229,29 @@ void LR_Rotate(tree_node_t *parent,tree_node_t *node) ...@@ -227,17 +229,29 @@ void LR_Rotate(tree_node_t *parent,tree_node_t *node)
node->left_node=temp; node->left_node=temp;
temp->parent_node=node; temp->parent_node=node;
parent->left_node=node_right; parent->left_node=node_right;
if(node_right!=NULL)
{
node_right->parent_node=parent;
}
temp->right_node=node_left; temp->right_node=node_left;
if(node_left!=NULL)
{
node_left->parent_node=temp;
}
} }
void RR_Rotate(tree_node_t *parent,tree_node_t *node) void RR_Rotate(tree_node_t *parent,tree_node_t *node)
{ {
printf("Came to RR\n"); // printf("Came to RR1\n");
tree_node_t *p_parent=parent->parent_node; tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->right_node; tree_node_t *temp=parent->right_node;
tree_node_t *temp_left=temp->left_node; tree_node_t *temp_left=temp->left_node;
if(p_parent==NULL) if(p_parent==NULL)
{ {
*root=temp; *root=temp;
...@@ -245,35 +259,39 @@ void RR_Rotate(tree_node_t *parent,tree_node_t *node) ...@@ -245,35 +259,39 @@ void RR_Rotate(tree_node_t *parent,tree_node_t *node)
} }
else else
{ {
temp->parent_node=p_parent; temp->parent_node=p_parent;
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent); if(p_parent->left_node==parent)
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
if(temp_meta_data->block_size<=p_parent_meta_data->block_size)
{ {
p_parent->left_node=temp; p_parent->left_node=temp;
} }
else else if(p_parent->right_node==parent)
{ {
p_parent->right_node=temp; p_parent->right_node=temp;
} }
}
temp->left_node=parent;
parent->parent_node=temp; temp->left_node=parent;
parent->right_node=temp_left;
parent->parent_node=temp;
parent->right_node=temp_left;
if(temp_left!=NULL)
{
temp_left->parent_node=parent;
} }
} }
void RL_Rotate(tree_node_t *parent,tree_node_t *node) void RL_Rotate(tree_node_t *parent,tree_node_t *node)
{ {
printf("Came to RL\n"); // printf("Came to RL\n");
tree_node_t *p_parent=parent->parent_node; tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->right_node; tree_node_t *temp=parent->right_node;
tree_node_t *temp_right=temp->right_node; //tree_node_t *temp_right=temp->right_node;
tree_node_t *node_left=node->left_node; tree_node_t *node_left=node->left_node;
tree_node_t *node_right=node->right_node; tree_node_t *node_right=node->right_node;
...@@ -286,15 +304,12 @@ void RL_Rotate(tree_node_t *parent,tree_node_t *node) ...@@ -286,15 +304,12 @@ void RL_Rotate(tree_node_t *parent,tree_node_t *node)
else else
{ {
node->parent_node=p_parent; node->parent_node=p_parent;
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *node_meta_data=meta_data_block_addr(node);
if(node_meta_data->block_size<=p_parent_meta_data->block_size) if(p_parent->left_node==parent)
{ {
p_parent->left_node=node; p_parent->left_node=node;
} }
else else if(p_parent->right_node==parent)
{ {
p_parent->right_node=node; p_parent->right_node=node;
} }
...@@ -306,51 +321,15 @@ void RL_Rotate(tree_node_t *parent,tree_node_t *node) ...@@ -306,51 +321,15 @@ void RL_Rotate(tree_node_t *parent,tree_node_t *node)
node->right_node=temp; node->right_node=temp;
temp->parent_node=node; temp->parent_node=node;
parent->right_node=node_right; parent->right_node=node_right;
temp->left_node=node_left; if(node_right!=NULL)
}
void rotate(tree_node_t *parent,tree_node_t *node)
{
block_meta_data_t *parent_meta_data=meta_data_block_addr(parent);
block_meta_data_t *node_meta_data=meta_data_block_addr(node);
if(parent_meta_data->block_size<node_meta_data->block_size)
{ {
tree_node_t *temp=parent->right_node; node_right->parent_node=parent;
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
if(temp_meta_data->block_size<node_meta_data->block_size)
{
RR_Rotate(parent,node);
}
else
{
RL_Rotate(parent,node);
}
} }
temp->left_node=node_left;
else if(node_left!=NULL)
{ {
node_left->parent_node=temp;
tree_node_t *temp=parent->left_node;
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
if(temp_meta_data->block_size<node_meta_data->block_size)
{
inorderTraversal(*root);
LR_Rotate(parent,node);
}
else
{
LL_rotate(parent,node);
}
} }
} }
int getHeight(tree_node_t *node) int getHeight(tree_node_t *node)
...@@ -361,8 +340,11 @@ int getHeight(tree_node_t *node) ...@@ -361,8 +340,11 @@ int getHeight(tree_node_t *node)
} }
int left_height=getHeight(node->left_node); int left_height=getHeight(node->left_node);
int right_height=getHeight(node->right_node); int right_height=getHeight(node->right_node);
return 1+(left_height>=right_height?left_height:right_height); return 1+(left_height>=right_height?left_height:right_height);
} }
...@@ -371,12 +353,11 @@ int get_balance(tree_node_t *node) ...@@ -371,12 +353,11 @@ int get_balance(tree_node_t *node)
if(node!=NULL) if(node!=NULL)
{ {
inorderTraversal(*root);
int left_height=getHeight(node->left_node); int left_height=getHeight(node->left_node);
int right_height=getHeight(node->right_node); int right_height=getHeight(node->right_node);
return (left_height-right_height); return (left_height-right_height);
} }
...@@ -384,24 +365,11 @@ int get_balance(tree_node_t *node) ...@@ -384,24 +365,11 @@ int get_balance(tree_node_t *node)
} }
void inorderTraversal(tree_node_t *node)
{
if(node!=NULL)
{
block_meta_data_t *meta_data_block=meta_data_block_addr(node);
printf("Block size=%d\n",(int)meta_data_block->block_size);
inorderTraversal(node->left_node);
inorderTraversal(node->right_node);
}
}
void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_block) void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_block)
{ {
// printf("Inserting block of size %d into free list\n",new_metadata_block->block_size);
tree_node_t *tree_root=*root; tree_node_t *tree_root=*root;
if(tree_root==NULL) if(tree_root==NULL)
...@@ -418,8 +386,10 @@ void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_ ...@@ -418,8 +386,10 @@ void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_
block_meta_data_t *meta_data=meta_data_block_addr(temp); block_meta_data_t *meta_data=meta_data_block_addr(temp);
if(new_metadata_block->block_size<=meta_data->block_size) if(new_metadata_block->block_size<=meta_data->block_size)
{ {
if(temp->left_node==NULL) if(temp->left_node==NULL)
{ {
new_metadata_block->tree_node.parent_node=temp; new_metadata_block->tree_node.parent_node=temp;
temp->left_node=&(new_metadata_block->tree_node); temp->left_node=&(new_metadata_block->tree_node);
temp=temp->left_node; temp=temp->left_node;
...@@ -434,6 +404,7 @@ void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_ ...@@ -434,6 +404,7 @@ void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_
else if(new_metadata_block->block_size>meta_data->block_size) else if(new_metadata_block->block_size>meta_data->block_size)
{ {
if(temp->right_node==NULL) if(temp->right_node==NULL)
{ {
new_metadata_block->tree_node.parent_node=temp; new_metadata_block->tree_node.parent_node=temp;
...@@ -452,15 +423,73 @@ void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_ ...@@ -452,15 +423,73 @@ void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_
while(parent) while(parent)
{ {
int b=get_balance(parent); int b=get_balance(parent);
if(b>=2||b<=-2) if(b>=2||b<=-2)
{ {
rotate(parent,temp); if(b<-1)
{
if(parent->right_node->right_node!=NULL)
{
if(parent->right_node->left_node!=NULL)
{
if(getHeight(parent->right_node->left_node)>getHeight(parent->right_node->right_node))
{
RL_Rotate(parent,parent->right_node->left_node);
}
else
{
RR_Rotate(parent,parent->right_node->right_node);
}
}
else
{
RR_Rotate(parent,parent->right_node->right_node);
}
}
else
{
RL_Rotate(parent,parent->right_node->left_node);
}
} }
parent=parent->parent_node; else if(b>1)
{
if(parent->left_node->left_node!=NULL)
{
if(parent->left_node->right_node!=NULL)
{
if(getHeight(parent->left_node->right_node)>getHeight(parent->left_node->left_node))
{
LR_Rotate(parent,parent->left_node->right_node);
}
else
{
LL_rotate(parent,parent->left_node->left_node);
}
}
else
{
LL_rotate(parent,parent->left_node->left_node);
}
}
else
{
LR_Rotate(parent,parent->left_node->right_node);
}
}
}
parent=parent->parent_node;
} }
} }
} }
...@@ -482,14 +511,13 @@ block_meta_data_t *get_node_from_tree(tree_node_t **root,uint32_t reqsize) ...@@ -482,14 +511,13 @@ block_meta_data_t *get_node_from_tree(tree_node_t **root,uint32_t reqsize)
return meta_data; return meta_data;
} }
tree_node_t *get_min_node(tree_node_t *root) tree_node_t *get_min_node(tree_node_t *root_node)
{ {
tree_node_t *temp=root; tree_node_t *temp=root_node;
while(temp->left_node!=NULL) while(temp->left_node!=NULL)
{ {
temp=temp->left_node; temp=temp->left_node;
} }
...@@ -503,10 +531,6 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -503,10 +531,6 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
tree_node_t *parent_node=del_node->parent_node; tree_node_t *parent_node=del_node->parent_node;
block_meta_data_t *parent_meta_data=meta_data_block_addr(parent_node);
block_meta_data_t *del_meta_data=meta_data_block_addr(del_node);
if(del_node->left_node==NULL||del_node->right_node==NULL) if(del_node->left_node==NULL||del_node->right_node==NULL)
{ {
...@@ -515,16 +539,17 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -515,16 +539,17 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
//Deleting a leaf node //Deleting a leaf node
if(temp==NULL) if(temp==NULL)
{ {
if(parent_node==NULL) if(parent_node==NULL)
{ {
*root=NULL; *root=NULL;
return; return;
} }
if(parent_meta_data->block_size<del_meta_data->block_size) else if(parent_node->right_node==del_node)
{ {
parent_node->right_node=NULL; parent_node->right_node=NULL;
} }
else else if(parent_node->left_node==del_node)
{ {
parent_node->left_node=NULL; parent_node->left_node=NULL;
} }
...@@ -535,6 +560,7 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -535,6 +560,7 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
else else
{ {
if(del_node->left_node!=NULL) if(del_node->left_node!=NULL)
{ {
del_node->left_node->parent_node=parent_node; del_node->left_node->parent_node=parent_node;
...@@ -546,13 +572,14 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -546,13 +572,14 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
del_node->parent_node=NULL; del_node->parent_node=NULL;
return; return;
} }
else if(parent_meta_data->block_size<del_meta_data->block_size) else if(parent_node->right_node==del_node)
{ {
parent_node->right_node=del_node->left_node; parent_node->right_node=del_node->left_node;
} }
else else if(parent_node->left_node==del_node)
{ {
parent_node->left_node=del_node->left_node; parent_node->left_node=del_node->left_node;
} }
} }
...@@ -568,12 +595,12 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -568,12 +595,12 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
del_node->parent_node=NULL; del_node->parent_node=NULL;
return; return;
} }
else if(parent_meta_data->block_size<del_meta_data->block_size) else if(parent_node->right_node==del_node)
{ {
parent_node->right_node=del_node->right_node; parent_node->right_node=del_node->right_node;
} }
else else if(parent_node->left_node==del_node)
{ {
parent_node->left_node=del_node->right_node; parent_node->left_node=del_node->right_node;
} }
...@@ -583,13 +610,31 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -583,13 +610,31 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
while(parent_node) while(parent_node)
{ {
int b=get_balance(parent_node); int b=get_balance(parent_node);
if(b<-1) if(b<-1)
{ {
if(parent_node->right_node->right_node!=NULL) if(parent_node->right_node->right_node!=NULL)
{ {
if(parent_node->right_node->left_node!=NULL)
{
if(getHeight(parent_node->right_node->left_node)>getHeight(parent_node->right_node->right_node))
{
RL_Rotate(parent_node,parent_node->right_node->left_node);
}
else
{
RR_Rotate(parent_node,parent_node->right_node->right_node);
}
}
else
{
RR_Rotate(parent_node,parent_node->right_node->right_node); RR_Rotate(parent_node,parent_node->right_node->right_node);
}
} }
else else
{ {
RL_Rotate(parent_node,parent_node->right_node->left_node); RL_Rotate(parent_node,parent_node->right_node->left_node);
...@@ -600,7 +645,26 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -600,7 +645,26 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
{ {
if(parent_node->left_node->left_node!=NULL) if(parent_node->left_node->left_node!=NULL)
{ {
if(parent_node->left_node->right_node!=NULL)
{
if(getHeight(parent_node->left_node->right_node)>getHeight(parent_node->left_node->left_node))
{
LR_Rotate(parent_node,parent_node->left_node->right_node);
}
else
{
LL_rotate(parent_node,parent_node->left_node->left_node);
}
}
else
{
LL_rotate(parent_node,parent_node->left_node->left_node); LL_rotate(parent_node,parent_node->left_node->left_node);
}
} }
else else
...@@ -609,35 +673,21 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -609,35 +673,21 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
} }
} }
parent_node=parent_node->parent_node; parent_node=parent_node->parent_node;
} }
} }
//Deleting node having two children //Deleting node having two children
else else
{ {
tree_node_t *min_right_node=get_min_node(del_node->right_node); tree_node_t *min_right_node=get_min_node(del_node->right_node);
remove_block_from_tree(root,min_right_node); remove_block_from_tree(root,min_right_node);
tree_node_t *parent_node_1=del_node->parent_node; tree_node_t *parent_node_1=del_node->parent_node;
block_meta_data_t *parent_meta_data_1=meta_data_block_addr(parent_node_1);
if(parent_node_1==NULL)
{
*root=min_right_node;
}
else if(parent_meta_data_1->block_size<del_meta_data->block_size)
{
parent_node_1->right_node=min_right_node;
}
else
{
parent_node_1->left_node=min_right_node;
}
min_right_node->left_node=del_node->left_node; min_right_node->left_node=del_node->left_node;
if(del_node->left_node!=NULL) if(del_node->left_node!=NULL)
...@@ -653,6 +703,24 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node) ...@@ -653,6 +703,24 @@ void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
} }
min_right_node->parent_node=parent_node_1; min_right_node->parent_node=parent_node_1;
if(parent_node_1==NULL)
{
*root=min_right_node;
}
else if(parent_node_1->right_node==del_node)
{
parent_node_1->right_node=min_right_node;
}
else if(parent_node_1->left_node==del_node)
{
parent_node_1->left_node=min_right_node;
}
} }
del_node->left_node=NULL; del_node->left_node=NULL;
...@@ -686,22 +754,30 @@ void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second) ...@@ -686,22 +754,30 @@ 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,uint32_t final_remain)
{ {
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;
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;
if(c == 0) if(final_remain < META_DATA_OVERHEAD)
meta_data_block->next_block = free_block->next_block->next_block; {
else if(meta_data_block->next_block)
meta_data_block->next_block = free_block->next_block; meta_data_block->next_block->prev_block = meta_data_block;
new_block->block_size = (uint32_t)final_remain; return;
}
block_meta_data_t *new_block = (block_meta_data_t *)NEXT_META_BLOCK_BY_SIZE(meta_data_block);
new_block->block_size = final_remain-META_DATA_OVERHEAD;
new_block->tree_node = init_free_node(); new_block->tree_node = init_free_node();
new_block->is_free = MM_TRUE; new_block->is_free = MM_TRUE;
mm_bind_blocks_for_allocation(meta_data_block, new_block); mm_bind_blocks_for_allocation(meta_data_block, new_block);
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,10 +785,11 @@ void create_new_block_and_insert_into_freelist(block_meta_data_t *meta_data_bloc ...@@ -709,10 +785,11 @@ 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+ALIGN(sizeof(block_end_meta_data_t))+ALIGN(sizeof(block_meta_data_t))+sys_page_size-1)/sys_page_size); int no_of_pages_req=((size+2*ALIGN(sizeof(block_end_meta_data_t))+2*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 *store_brk = mem_heap_hi()+1;
void *brk= mem_sbrk(extra_size_req); void *brk= mem_sbrk(extra_size_req);
if(*(int *)brk==-1) if(store_brk==brk && *(int *)brk == -1)
return NULL; return NULL;
return brk; return brk;
} }
...@@ -769,6 +846,8 @@ void *mm_malloc(size_t size) ...@@ -769,6 +846,8 @@ 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;
} }
...@@ -779,7 +858,6 @@ void *mm_malloc(size_t size) ...@@ -779,7 +858,6 @@ void *mm_malloc(size_t 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+ALIGN(sizeof(block_end_meta_data_t))+ALIGN(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) if(brk==NULL)
...@@ -813,11 +891,15 @@ void *mm_malloc(size_t size) ...@@ -813,11 +891,15 @@ void *mm_malloc(size_t size)
next_end_meta_data_block->block_size=next_meta_data_block->block_size; next_end_meta_data_block->block_size=next_meta_data_block->block_size;
int new_free_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))));
if(new_free_block_size>0)
{
block_meta_data_t *new_free_meta_block=NEXT_META_BLOCK_BY_SIZE(next_meta_data_block); block_meta_data_t *new_free_meta_block=NEXT_META_BLOCK_BY_SIZE(next_meta_data_block);
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)((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->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();
...@@ -831,13 +913,16 @@ void *mm_malloc(size_t size) ...@@ -831,13 +913,16 @@ void *mm_malloc(size_t size)
insert_node_in_freelist(root,new_free_meta_block); insert_node_in_freelist(root,new_free_meta_block);
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 *)((char *)next_meta_data_block+ALIGN(sizeof(block_meta_data_t))); 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); remove_block_from_tree(root,&free_metadata_block->tree_node);
uint32_t remaining_size=free_metadata_block->block_size-size; uint32_t remaining_size=free_metadata_block->block_size-size;
...@@ -849,9 +934,6 @@ void *mm_malloc(size_t size) ...@@ -849,9 +934,6 @@ void *mm_malloc(size_t size)
end_meta_data->block_size=size; end_meta_data->block_size=size;
remove_block_from_tree(root,&free_metadata_block->tree_node);
//Here we will created new block by splitting previous block
if(ALIGN(sizeof(block_meta_data_t))+ALIGN(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;
...@@ -875,8 +957,6 @@ void *mm_malloc(size_t size) ...@@ -875,8 +957,6 @@ void *mm_malloc(size_t size)
mm_bind_blocks_for_allocation(free_metadata_block,next_meta_block); mm_bind_blocks_for_allocation(free_metadata_block,next_meta_block);
} }
return (void *)((char *)free_metadata_block+ALIGN(sizeof(block_meta_data_t))); 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.
...@@ -896,8 +976,10 @@ void mm_free(void *ptr) ...@@ -896,8 +976,10 @@ void mm_free(void *ptr)
* It should also keep track of all the free memory blocks. * 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 * 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] %d\n",c);
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-ALIGN(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);
...@@ -941,6 +1023,8 @@ void mm_free(void *ptr) ...@@ -941,6 +1023,8 @@ void mm_free(void *ptr)
{ {
remove_block_from_tree(root,&prev_meta_data_block->tree_node); remove_block_from_tree(root,&prev_meta_data_block->tree_node);
prev_meta_data_block->block_size += get_internal_fragmented_size(prev_meta_data_block,meta_data_block);
merge_free_blocks(prev_meta_data_block,meta_data_block); merge_free_blocks(prev_meta_data_block,meta_data_block);
merged_meta_data_block=prev_meta_data_block; merged_meta_data_block=prev_meta_data_block;
...@@ -958,6 +1042,7 @@ void mm_free(void *ptr) ...@@ -958,6 +1042,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
...@@ -970,7 +1055,6 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -970,7 +1055,6 @@ void *mm_realloc(void *ptr, size_t size)
} }
/* /*
* 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.
* You can use 'memcpy()' for this purpose. * You can use 'memcpy()' for this purpose.
...@@ -982,7 +1066,7 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -982,7 +1066,7 @@ void *mm_realloc(void *ptr, size_t size)
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-ALIGN(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 *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
if(size < meta_data_block->block_size) if(size < meta_data_block->block_size)
...@@ -1054,67 +1138,64 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -1054,67 +1138,64 @@ void *mm_realloc(void *ptr, size_t size)
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 *)((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. 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 && meta_data_block->prev_block && meta_data_block->prev_block->is_free==MM_TRUE && \
req_rem_size <= TOTAL_COMBINED_SIZE_OF_BLOCKS(meta_data_block)+inter_frag)
{
remove_block_from_tree(root,&meta_data_block->prev_block->tree_node);
remove_block_from_tree(root,&meta_data_block->next_block->tree_node);
req_rem_size -= inter_frag;
inter_frag = get_internal_fragmented_size(meta_data_block->prev_block,meta_data_block);
req_rem_size -= inter_frag;
uint32_t final_remain = abs(meta_data_block->next_block->block_size+meta_data_block->prev_block->block_size+2*ALIGN(sizeof(block_end_meta_data_t)) \
+2*ALIGN(sizeof(block_meta_data_t)) - req_rem_size);
meta_data_block->prev_block->block_size = size;
meta_data_block = meta_data_block->prev_block;
block_meta_data_t *store_head = meta_data_block->next_block;
meta_data_block->next_block = meta_data_block->next_block->next_block->next_block;
meta_data_block->is_free = MM_FALSE;
memcpy((char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(store_head)+ALIGN(sizeof(block_meta_data_t)),store_head->block_size);
create_new_block_and_insert_into_freelist(meta_data_block,final_remain);
return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
}
if(meta_data_block->next_block && meta_data_block->next_block->is_free == MM_TRUE && \ 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)) 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); 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; 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); uint32_t final_remain = TOTAL_COMBINE_SIZE_OF_BLOCKS(meta_data_block->next_block) - req_rem_size;
end_meta_data_block->block_size = meta_data_block->block_size; meta_data_block->block_size = size;
if( final_remain > META_DATA_OVERHEAD) //block_meta_data_t *store_head = meta_data_block->next_block;
{ meta_data_block->next_block = meta_data_block->next_block->next_block;
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,final_remain);
}
return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t))); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
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)){
inter_frag = get_internal_fragmented_size(meta_data_block->prev_block,meta_data_block);
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;
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)+ALIGN(sizeof(block_meta_data_t)), (char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)),meta_data_block->block_size); meta_data_block->prev_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;
meta_data_block = meta_data_block->prev_block; meta_data_block = meta_data_block->prev_block;
if( final_remain > META_DATA_OVERHEAD) meta_data_block->is_free = MM_FALSE;
create_new_block_and_insert_into_freelist(meta_data_block,meta_data_block->next_block,final_remain,1); block_meta_data_t *store_head = meta_data_block->next_block;
meta_data_block->next_block = meta_data_block->next_block->next_block;
memcpy((char *)(meta_data_block)+ALIGN(sizeof(block_meta_data_t)), (char *)(store_head)+ALIGN(sizeof(block_meta_data_t)),store_head->block_size);
create_new_block_and_insert_into_freelist(meta_data_block,final_remain);
return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t))); return (void *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
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_tree(root,&meta_data_block->prev_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;
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)+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);
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 *)((char *)meta_data_block+ALIGN(sizeof(block_meta_data_t)));
}
void *ptr = mm_malloc(size); void *ptr = mm_malloc(size);
block_meta_data_t *new_meta_data_block = (block_meta_data_t *)((char *)ptr-ALIGN(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;
...@@ -1123,36 +1204,4 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -1123,36 +1204,4 @@ void *mm_realloc(void *ptr, size_t size)
return (void *)((char *)new_meta_data_block+ALIGN(sizeof(block_meta_data_t))); return (void *)((char *)new_meta_data_block+ALIGN(sizeof(block_meta_data_t)));
} }
mm_free(ptr);
return mem_sbrk(size);
}
int main()
{
mm_init();
void *p1=mm_malloc(40);
void *p3=mm_malloc(60);
void *p4=mm_malloc(100);
void *p5=mm_malloc(20);
void *p6=mm_malloc(90);
void *p7=mm_malloc(3500);
printf("Above Call Executed\n");
// mm_free(p2);
mm_free(p4);
mm_free(p6);
mm_free(p1);
// mm_free(p3);
// mm_free(p5);
// mm_free(p7);
printf("[FINAL INORDER TRAVERSAL]\n");
inorderTraversal(*root);
//mm_free(p2);
//mm_free(p2);
//void *p4=mm_malloc(40);
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