Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
MallocProject
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vadapalli K Chaitanya
MallocProject
Commits
c57e5571
Commit
c57e5571
authored
Oct 13, 2020
by
Shivaji
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
realloc for mm2.c
parent
54d4563a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1033 additions
and
30 deletions
+1033
-30
mm2.c
mm2.c
+1033
-30
No files found.
mm2.c
View file @
c57e5571
/*
* mm-naive.c - The fastest, least memory-efficient malloc package.
*
*
* In this naive approach, a block is allocated by simply incrementing
* the brk pointer. A block is pure payload. There are no headers or
* footers. Blocks are never coalesced or reused. Realloc is
...
...
@@ -35,6 +35,85 @@ team_t team = {
"member_2@cse.iitb.ac.in"
};
typedef
struct
tree_node_
{
struct
tree_node_
*
left_node
;
struct
tree_node_
*
right_node
;
struct
tree_node_
*
parent_node
;
}
tree_node_t
;
typedef
enum
{
MM_FALSE
,
MM_TRUE
}
vm_bool_t
;
typedef
struct
block_meta_data_
{
vm_bool_t
is_free
;
uint32_t
block_size
;
struct
block_meta_data_
*
prev_block
;
struct
block_meta_data_
*
next_block
;
tree_node_t
tree_node
;
}
block_meta_data_t
;
typedef
struct
printer
{
int
rollno
;
char
*
name
;
struct
printer
*
next
;
}
printer
;
typedef
struct
block_end_meta_data_
{
uint32_t
block_size
;
}
block_end_meta_data_t
;
#define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \
(block_meta_data_t *)((char *)(block_meta_data_ptr+1) \
+ block_meta_data_ptr->block_size \
+sizeof(block_end_meta_data_t))
#define mm_bind_blocks_for_allocation(allocated_meta_block,free_meta_block) \
free_meta_block->prev_block=allocated_meta_block; \
free_meta_block->next_block=allocated_meta_block->next_block; \
allocated_meta_block->next_block=free_meta_block; \
if(free_meta_block->next_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) \
(block_meta_data_t *) ((char *)(free_node_addr)-offsetof(block_meta_data_t,tree_node))
#define end_meta_data_addr(meta_data_addr) \
(block_end_meta_data_t *)((char *)(meta_data_addr+1) \
+meta_data_addr->block_size)
#define start_meta_data_addr(end_meta_data_addr) \
(block_meta_data_t *)((char *)(end_meta_data_addr) \
-end_meta_data_addr->block_size \
-sizeof(block_meta_data_t))
#define META_DATA_OVERHEAD \
(uint32_t)(sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t))
#define TOTAL_COMBINE_SIZE_OF_BLOCKS(base) \
base->block_size \
+sizeof(block_end_meta_data_t) \
+sizeof(block_meta_data_t)
#define TOTAL_COMBINED_SIZE_OF_BLOCKS(base) \
base->next_block->block_size \
+base->prev_block->block_size \
+2*sizeof(block_end_meta_data_t) \
+2*sizeof(block_meta_data_t)
/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8
...
...
@@ -44,36 +123,645 @@ team_t team = {
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
/*
/*
* mm_init - initialize the malloc package.
*/
tree_node_t
init_free_node
(
void
)
{
tree_node_t
treenode
;
treenode
.
left_node
=
NULL
;
treenode
.
right_node
=
NULL
;
treenode
.
parent_node
=
NULL
;
return
treenode
;
}
void
remove_block_from_tree
(
tree_node_t
**
root
,
tree_node_t
*
del_node
);
void
*
init_mem_sbrk_break
=
NULL
;
tree_node_t
**
root
=
NULL
;
void
LL_rotate
(
tree_node_t
*
parent
,
tree_node_t
*
node
)
{
printf
(
"Came to LL
\n
"
);
tree_node_t
*
p_parent
=
parent
->
parent_node
;
tree_node_t
*
temp
=
parent
->
left_node
;
tree_node_t
*
temp_right
=
temp
->
right_node
;
if
(
p_parent
==
NULL
)
{
*
root
=
temp
;
temp
->
parent_node
=
NULL
;
}
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
;
if
(
temp_meta_data
->
block_size
<=
p_parent_meta_data
->
block_size
)
{
p_parent
->
left_node
=
temp
;
}
else
{
p_parent
->
right_node
=
temp
;
}
}
temp
->
right_node
=
parent
;
parent
->
parent_node
=
temp
;
parent
->
left_node
=
temp_right
;
}
void
LR_Rotate
(
tree_node_t
*
parent
,
tree_node_t
*
node
)
{
printf
(
"Came to LR
\n
"
);
tree_node_t
*
p_parent
=
parent
->
parent_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_right
=
node
->
right_node
;
if
(
p_parent
==
NULL
)
{
*
root
=
node
;
node
->
parent_node
=
NULL
;
}
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
;
if
(
node_meta_data
->
block_size
<=
p_parent_meta_data
->
block_size
)
{
p_parent
->
left_node
=
node
;
}
else
{
p_parent
->
right_node
=
node
;
}
}
node
->
right_node
=
parent
;
parent
->
parent_node
=
node
;
node
->
left_node
=
temp
;
temp
->
parent_node
=
node
;
parent
->
left_node
=
node_right
;
temp
->
right_node
=
node_left
;
}
void
RR_Rotate
(
tree_node_t
*
parent
,
tree_node_t
*
node
)
{
printf
(
"Came to RR
\n
"
);
tree_node_t
*
p_parent
=
parent
->
parent_node
;
tree_node_t
*
temp
=
parent
->
right_node
;
tree_node_t
*
temp_left
=
temp
->
left_node
;
if
(
p_parent
==
NULL
)
{
*
root
=
temp
;
temp
->
parent_node
=
NULL
;
}
else
{
temp
->
parent_node
=
p_parent
;
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
);
if
(
temp_meta_data
->
block_size
<=
p_parent_meta_data
->
block_size
)
{
p_parent
->
left_node
=
temp
;
}
else
{
p_parent
->
right_node
=
temp
;
}
temp
->
left_node
=
parent
;
parent
->
parent_node
=
temp
;
parent
->
right_node
=
temp_left
;
}
}
void
RL_Rotate
(
tree_node_t
*
parent
,
tree_node_t
*
node
)
{
printf
(
"Came to RL
\n
"
);
tree_node_t
*
p_parent
=
parent
->
parent_node
;
tree_node_t
*
temp
=
parent
->
right_node
;
tree_node_t
*
temp_right
=
temp
->
right_node
;
tree_node_t
*
node_left
=
node
->
left_node
;
tree_node_t
*
node_right
=
node
->
right_node
;
if
(
p_parent
==
NULL
)
{
*
root
=
node
;
node
->
parent_node
=
NULL
;
}
else
{
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
)
{
p_parent
->
left_node
=
node
;
}
else
{
p_parent
->
right_node
=
node
;
}
}
node
->
left_node
=
parent
;
parent
->
parent_node
=
node
;
node
->
right_node
=
temp
;
temp
->
parent_node
=
node
;
parent
->
right_node
=
node_right
;
temp
->
left_node
=
node_left
;
}
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
;
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
);
}
}
else
{
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
)
{
if
(
node
==
NULL
)
{
return
0
;
}
int
left_height
=
getHeight
(
node
->
left_node
);
int
right_height
=
getHeight
(
node
->
right_node
);
return
1
+
(
left_height
>=
right_height
?
left_height
:
right_height
);
}
int
get_balance
(
tree_node_t
*
node
)
{
if
(
node
!=
NULL
)
{
inorderTraversal
(
*
root
);
int
left_height
=
getHeight
(
node
->
left_node
);
int
right_height
=
getHeight
(
node
->
right_node
);
return
(
left_height
-
right_height
);
}
return
0
;
}
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
)
{
tree_node_t
*
tree_root
=*
root
;
if
(
tree_root
==
NULL
)
{
*
root
=&
(
new_metadata_block
->
tree_node
);
}
else
{
tree_node_t
*
temp
=
tree_root
;
while
(
temp
)
{
block_meta_data_t
*
meta_data
=
meta_data_block_addr
(
temp
);
if
(
new_metadata_block
->
block_size
<=
meta_data
->
block_size
)
{
if
(
temp
->
left_node
==
NULL
)
{
new_metadata_block
->
tree_node
.
parent_node
=
temp
;
temp
->
left_node
=&
(
new_metadata_block
->
tree_node
);
temp
=
temp
->
left_node
;
break
;
}
else
{
temp
=
temp
->
left_node
;
}
}
else
if
(
new_metadata_block
->
block_size
>
meta_data
->
block_size
)
{
if
(
temp
->
right_node
==
NULL
)
{
new_metadata_block
->
tree_node
.
parent_node
=
temp
;
temp
->
right_node
=&
(
new_metadata_block
->
tree_node
);
temp
=
temp
->
right_node
;
break
;
}
else
{
temp
=
temp
->
right_node
;
}
}
}
tree_node_t
*
parent
=
temp
->
parent_node
;
while
(
parent
)
{
int
b
=
get_balance
(
parent
);
if
(
b
>=
2
||
b
<=-
2
)
{
rotate
(
parent
,
temp
);
}
parent
=
parent
->
parent_node
;
}
}
}
block_meta_data_t
*
get_node_from_tree
(
tree_node_t
**
root
,
uint32_t
reqsize
)
{
tree_node_t
*
temp
=*
root
;
while
(
temp
->
right_node
!=
NULL
)
{
temp
=
temp
->
right_node
;
}
block_meta_data_t
*
meta_data
=
NULL
;
meta_data
=
meta_data_block_addr
(
temp
);
return
meta_data
;
}
tree_node_t
*
get_min_node
(
tree_node_t
*
root
)
{
tree_node_t
*
temp
=
root
;
while
(
temp
->
left_node
!=
NULL
)
{
temp
=
temp
->
left_node
;
}
return
temp
;
}
void
remove_block_from_tree
(
tree_node_t
**
root
,
tree_node_t
*
del_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
)
{
tree_node_t
*
temp
=
del_node
->
left_node
!=
NULL
?
del_node
->
left_node
:
del_node
->
right_node
;
//Deleting a leaf node
if
(
temp
==
NULL
)
{
if
(
parent_node
==
NULL
)
{
*
root
=
NULL
;
return
;
}
if
(
parent_meta_data
->
block_size
<
del_meta_data
->
block_size
)
{
parent_node
->
right_node
=
NULL
;
}
else
{
parent_node
->
left_node
=
NULL
;
}
}
//Deleting node having 1 child
else
{
if
(
del_node
->
left_node
!=
NULL
)
{
del_node
->
left_node
->
parent_node
=
parent_node
;
if
(
parent_node
==
NULL
)
{
*
root
=
del_node
->
left_node
;
del_node
->
left_node
=
NULL
;
del_node
->
right_node
=
NULL
;
del_node
->
parent_node
=
NULL
;
return
;
}
else
if
(
parent_meta_data
->
block_size
<
del_meta_data
->
block_size
)
{
parent_node
->
right_node
=
del_node
->
left_node
;
}
else
{
parent_node
->
left_node
=
del_node
->
left_node
;
}
}
else
{
del_node
->
right_node
->
parent_node
=
parent_node
;
if
(
parent_node
==
NULL
)
{
*
root
=
del_node
->
right_node
;
del_node
->
left_node
=
NULL
;
del_node
->
right_node
=
NULL
;
del_node
->
parent_node
=
NULL
;
return
;
}
else
if
(
parent_meta_data
->
block_size
<
del_meta_data
->
block_size
)
{
parent_node
->
right_node
=
del_node
->
right_node
;
}
else
{
parent_node
->
left_node
=
del_node
->
right_node
;
}
}
}
//Balancing parent node
while
(
parent_node
)
{
int
b
=
get_balance
(
parent_node
);
if
(
b
<-
1
)
{
if
(
parent_node
->
right_node
->
right_node
!=
NULL
)
{
RR_Rotate
(
parent_node
,
parent_node
->
right_node
->
right_node
);
}
else
{
RL_Rotate
(
parent_node
,
parent_node
->
right_node
->
left_node
);
}
}
if
(
b
>
1
)
{
if
(
parent_node
->
left_node
->
left_node
!=
NULL
)
{
LL_rotate
(
parent_node
,
parent_node
->
left_node
->
left_node
);
}
else
{
LR_Rotate
(
parent_node
,
parent_node
->
left_node
->
right_node
);
}
}
parent_node
=
parent_node
->
parent_node
;
}
}
//Deleting node having two children
else
{
tree_node_t
*
min_right_node
=
get_min_node
(
del_node
->
right_node
);
remove_block_from_tree
(
root
,
min_right_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
;
if
(
del_node
->
left_node
!=
NULL
)
{
del_node
->
left_node
->
parent_node
=
min_right_node
;
}
min_right_node
->
right_node
=
del_node
->
right_node
;
if
(
del_node
->
right_node
!=
NULL
)
{
del_node
->
right_node
->
parent_node
=
min_right_node
;
}
min_right_node
->
parent_node
=
parent_node_1
;
}
del_node
->
left_node
=
NULL
;
del_node
->
right_node
=
NULL
;
del_node
->
parent_node
=
NULL
;
}
int
get_internal_fragmented_size
(
block_meta_data_t
*
block1
,
block_meta_data_t
*
block2
)
{
block_meta_data_t
*
next_meta_block_by_size
=
NEXT_META_BLOCK_BY_SIZE
(
block1
);
return
(
int
)((
char
*
)
block2
-
(
char
*
)
next_meta_block_by_size
);
}
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
);
first
->
block_size
+=
sizeof
(
block_meta_data_t
)
+
second
->
block_size
+
sizeof
(
block_end_meta_data_t
);
first
->
next_block
=
second
->
next_block
;
if
(
second
->
next_block
!=
NULL
)
{
second
->
next_block
->
prev_block
=
first
;
}
}
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
);
if
(
meta_data_block
->
is_free
==
MM_TRUE
)
meta_data_block
->
is_free
=
MM_FALSE
;
if
(
c
==
0
)
meta_data_block
->
next_block
=
free_block
->
next_block
->
next_block
;
else
meta_data_block
->
next_block
=
free_block
->
next_block
;
new_block
->
block_size
=
(
uint32_t
)
final_remain
;
new_block
->
tree_node
=
init_free_node
();
new_block
->
is_free
=
MM_TRUE
;
mm_bind_blocks_for_allocation
(
meta_data_block
,
new_block
);
assert
(
meta_data_block
->
next_block
->
block_size
==
new_block
->
block_size
);
block_end_meta_data_t
*
new_end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
new_block
);
new_end_meta_data_block
->
block_size
=
new_block
->
block_size
;
insert_node_in_freelist
(
root
,
new_block
);
}
void
*
allocate_requested_size
(
size_t
size
)
{
size_t
sys_page_size
=
mem_pagesize
();
int
no_of_pages_req
=
((
size
+
sizeof
(
block_end_meta_data_t
)
+
sizeof
(
block_meta_data_t
)
+
sys_page_size
-
1
)
/
sys_page_size
);
size_t
extra_size_req
=
(
int
)
no_of_pages_req
*
sys_page_size
;
void
*
brk
=
mem_sbrk
(
extra_size_req
);
if
(
*
(
int
*
)
brk
==-
1
)
return
NULL
;
return
brk
;
}
int
mm_init
(
void
)
{
//This function is called every time before each test run of the trace.
//It should reset the entire state of your malloc or the consecutive trace runs will give wrong answer.
//It should reset the entire state of your malloc or the consecutive trace runs will give wrong answer.
/*
/*
* This function should initialize and reset any data structures used to represent the starting state(empty heap)
*
*
* This function will be called multiple time in the driver code "mdriver.c"
*/
if
(
init_mem_sbrk_break
==
NULL
)
{
mem_init
();
}
mem_reset_brk
();
init_mem_sbrk_break
=
mem_sbrk
(
mem_pagesize
());
if
(
*
(
int
*
)
init_mem_sbrk_break
==-
1
)
{
return
-
1
;
}
root
=
(
tree_node_t
**
)
init_mem_sbrk_break
;
block_meta_data_t
*
metadata
=
(
block_meta_data_t
*
)(
root
+
1
);
metadata
->
is_free
=
MM_TRUE
;
metadata
->
block_size
=
mem_pagesize
()
-
sizeof
(
block_meta_data_t
)
-
sizeof
(
block_end_meta_data_t
)
-
sizeof
(
root
);
metadata
->
tree_node
=
init_free_node
();
metadata
->
next_block
=
NULL
;
metadata
->
prev_block
=
NULL
;
*
root
=&
(
metadata
->
tree_node
);
block_end_meta_data_t
*
end_meta_data
=
end_meta_data_addr
(
metadata
);
end_meta_data
->
block_size
=
metadata
->
block_size
;
return
0
;
//Returns 0 on successfull initialization.
}
//---------------------------------------------------------------------------------------------------------------
/*
/*
* mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment.
*/
void
*
mm_malloc
(
size_t
size
)
{
/*
{
/*
* This function should keep track of the allocated memory blocks.
* The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory.
* The previously freed memory blocks should be reused.
...
...
@@ -85,66 +773,381 @@ void *mm_malloc(size_t size)
return
NULL
;
}
size
=
((
size
+
7
)
/
8
)
*
8
;
//size alligned to 8 bytes
return
mem_sbrk
(
size
);
//mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
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
(
free_metadata_block
==
NULL
||
free_metadata_block
->
block_size
<
(
size
+
sizeof
(
block_end_meta_data_t
)
+
sizeof
(
block_meta_data_t
)))
{
void
*
brk
=
allocate_requested_size
(
size
);
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
));
block_meta_data_t
*
prev_start_meta_data
=
NULL
;
prev_start_meta_data
=
start_meta_data_addr
(
prev_end_meta_data
);
block_meta_data_t
*
next_meta_data_block
=
(
block_meta_data_t
*
)
brk
;
next_meta_data_block
->
is_free
=
MM_FALSE
;
next_meta_data_block
->
block_size
=
size
;
next_meta_data_block
->
tree_node
=
init_free_node
();
next_meta_data_block
->
prev_block
=
prev_start_meta_data
;
prev_start_meta_data
->
next_block
=
next_meta_data_block
;
next_meta_data_block
->
next_block
=
NULL
;
block_end_meta_data_t
*
next_end_meta_data_block
=
end_meta_data_addr
(
next_meta_data_block
);
next_end_meta_data_block
->
block_size
=
next_meta_data_block
->
block_size
;
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->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
->
tree_node
=
init_free_node
();
new_free_meta_block
->
prev_block
=
NULL
;
block_end_meta_data_t
*
new_end_free_meta_block
=
end_meta_data_addr
(
new_free_meta_block
);
new_end_free_meta_block
->
block_size
=
new_free_meta_block
->
block_size
;
insert_node_in_freelist
(
root
,
new_free_meta_block
);
mm_bind_blocks_for_allocation
(
next_meta_data_block
,
new_free_meta_block
);
return
(
void
*
)(
next_meta_data_block
+
1
);
}
assert
(
free_metadata_block
->
is_free
==
MM_TRUE
);
printf
(
"Free Data block size=%d
\n
"
,(
int
)
free_metadata_block
->
block_size
);
uint32_t
remaining_size
=
free_metadata_block
->
block_size
-
size
;
free_metadata_block
->
is_free
=
MM_FALSE
;
free_metadata_block
->
block_size
=
size
;
block_end_meta_data_t
*
end_meta_data
=
end_meta_data_addr
(
free_metadata_block
);
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
(
sizeof
(
block_meta_data_t
)
+
sizeof
(
block_end_meta_data_t
)
<
remaining_size
){
block_meta_data_t
*
next_meta_block
=
NULL
;
block_end_meta_data_t
*
next_end_meta_block
=
NULL
;
next_meta_block
=
NEXT_META_BLOCK_BY_SIZE
(
free_metadata_block
);
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
->
tree_node
=
init_free_node
();
next_end_meta_block
=
end_meta_data_addr
(
next_meta_block
);
next_end_meta_block
->
block_size
=
next_meta_block
->
block_size
;
insert_node_in_freelist
(
root
,
next_meta_block
);
mm_bind_blocks_for_allocation
(
free_metadata_block
,
next_meta_block
);
}
return
(
void
*
)(
free_metadata_block
+
1
);
//mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
}
void
mm_free
(
void
*
ptr
)
{
/*
/*
* Searches the previously allocated node for memory block with base address ptr.
*
* It should also perform coalesceing on both ends i.e. if the consecutive memory blocks are
*
* It should also perform coalesceing on both ends i.e. if the consecutive memory blocks are
* free(not allocated) then they should be combined into a single block.
*
*
* It should also keep track of all the free memory blocks.
* If the freed block is at the end of the heap then you can also decrease the heap size
* If the freed block is at the end of the heap then you can also decrease the heap size
* using 'mem_sbrk(-size)'.
*/
block_meta_data_t
*
meta_data_block
=
(
block_meta_data_t
*
)((
char
*
)
ptr
-
sizeof
(
block_meta_data_t
));
assert
(
meta_data_block
->
is_free
==
MM_FALSE
);
meta_data_block
->
is_free
=
MM_TRUE
;
block_meta_data_t
*
prev_meta_data_block
=
meta_data_block
->
prev_block
;
block_meta_data_t
*
next_meta_data_block
=
meta_data_block
->
next_block
;
block_meta_data_t
*
merged_meta_data_block
=
NULL
;
block_end_meta_data_t
*
merged_end_meta_data_block
=
NULL
;
if
(
next_meta_data_block
!=
NULL
)
{
meta_data_block
->
block_size
+=
get_internal_fragmented_size
(
meta_data_block
,
next_meta_data_block
);
}
//If block being free is upper most block
else
{
int
fragmented_size
=
(
int
)((
char
*
)
mem_heap_hi
()
+
1
-
((
char
*
)
end_meta_data_addr
(
meta_data_block
)
+
sizeof
(
block_end_meta_data_t
)));
meta_data_block
->
block_size
+=
fragmented_size
;
}
merged_meta_data_block
=
meta_data_block
;
if
(
next_meta_data_block
!=
NULL
&&
next_meta_data_block
->
is_free
==
MM_TRUE
)
{
remove_block_from_tree
(
root
,
&
next_meta_data_block
->
tree_node
);
merge_free_blocks
(
meta_data_block
,
next_meta_data_block
);
merged_meta_data_block
=
meta_data_block
;
}
if
(
prev_meta_data_block
!=
NULL
&&
prev_meta_data_block
->
is_free
==
MM_TRUE
)
{
remove_block_from_tree
(
root
,
&
prev_meta_data_block
->
tree_node
);
merge_free_blocks
(
prev_meta_data_block
,
meta_data_block
);
merged_meta_data_block
=
prev_meta_data_block
;
}
merged_end_meta_data_block
=
(
block_end_meta_data_t
*
)(
end_meta_data_addr
(
merged_meta_data_block
));
merged_end_meta_data_block
->
block_size
=
merged_meta_data_block
->
block_size
;
insert_node_in_freelist
(
root
,
merged_meta_data_block
);
}
/*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/
void
*
mm_realloc
(
void
*
ptr
,
size_t
size
)
{
size
=
((
size
+
7
)
/
8
)
*
8
;
//8-byte alignement
{
size
=
((
size
+
7
)
/
8
)
*
8
;
//8-byte alignement
if
(
ptr
==
NULL
){
//memory was not previously allocated
return
mm_malloc
(
size
);
}
if
(
size
==
0
){
//new size is zero
mm_free
(
ptr
);
return
NULL
;
}
/*
* This function should also copy the content of the previous memory block into the new block.
* You can use 'memcpy()' for this purpose.
*
* The data structures corresponding to free memory blocks and allocated memory
*
* The data structures corresponding to free memory blocks and allocated memory
* blocks should also be updated.
*/
mm_free
(
ptr
);
return
mem_sbrk
(
size
);
}
block_meta_data_t
*
meta_data_block
=
(
block_meta_data_t
*
)((
char
*
)
ptr
-
sizeof
(
block_meta_data_t
));
if
(
size
==
meta_data_block
->
block_size
)
return
(
void
*
)(
meta_data_block
+
1
);
if
(
size
<
meta_data_block
->
block_size
)
{
uint32_t
original_size
=
(
uint32_t
)
meta_data_block
->
block_size
;
uint32_t
inter_frag
=
(
uint32_t
)
get_internal_fragmented_size
(
meta_data_block
,
meta_data_block
->
next_block
);
meta_data_block
->
block_size
=
size
;
block_end_meta_data_t
*
end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
meta_data_block
);
end_meta_data_block
->
block_size
=
meta_data_block
->
block_size
;
if
(
meta_data_block
->
next_block
&&
meta_data_block
->
next_block
->
is_free
==
MM_TRUE
)
{
block_meta_data_t
*
new_block
=
NEXT_META_BLOCK_BY_SIZE
(
meta_data_block
);
remove_block_from_tree
(
root
,
&
meta_data_block
->
next_block
->
tree_node
);
new_block
->
block_size
=
meta_data_block
->
next_block
->
block_size
+
inter_frag
+
(
original_size
-
size
);
meta_data_block
->
next_block
=
meta_data_block
->
next_block
->
next_block
;
new_block
->
is_free
=
MM_TRUE
;
new_block
->
tree_node
=
init_free_node
();
mm_bind_blocks_for_allocation
(
meta_data_block
,
new_block
);
block_end_meta_data_t
*
new_end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
new_block
);
new_end_meta_data_block
->
block_size
=
new_block
->
block_size
;
insert_node_in_freelist
(
root
,
new_block
);
return
(
void
*
)(
meta_data_block
+
1
);
}
else
{
uint32_t
inter_frag
=
0
;
int
fragmented_size
=
(
int
)((
char
*
)
mem_heap_hi
()
+
1
-
((
char
*
)
end_meta_data_addr
(
meta_data_block
)
+
sizeof
(
block_end_meta_data_t
)));
if
(
!
meta_data_block
->
next_block
){
if
(
(
fragmented_size
+
original_size
-
size
)
<
(
sizeof
(
block_end_meta_data_t
)
+
sizeof
(
end_meta_data_block
))
)
return
meta_data_block
;
}
else
{
uint32_t
inter_frag
=
get_internal_fragmented_size
(
meta_data_block
,
meta_data_block
->
next_block
);
if
(
(
inter_frag
+
original_size
-
size
)
<
(
sizeof
(
block_end_meta_data_t
)
+
sizeof
(
end_meta_data_block
))
)
return
meta_data_block
;
fragmented_size
=
0
;
}
meta_data_block
->
block_size
=
size
;
block_end_meta_data_t
*
end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
meta_data_block
);
end_meta_data_block
->
block_size
=
meta_data_block
->
block_size
;
if
((
original_size
-
size
+
inter_frag
+
fragmented_size
)
>
META_DATA_OVERHEAD
)
{
block_meta_data_t
*
new_block
=
(
block_meta_data_t
*
)
NEXT_META_BLOCK_BY_SIZE
(
meta_data_block
);
new_block
->
tree_node
=
init_free_node
();
new_block
->
is_free
=
MM_TRUE
;
new_block
->
block_size
=
original_size
-
size
+
inter_frag
+
fragmented_size
-
META_DATA_OVERHEAD
;
mm_bind_blocks_for_allocation
(
meta_data_block
,
new_block
);
block_end_meta_data_t
*
new_end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
new_block
);
new_end_meta_data_block
->
block_size
=
new_block
->
block_size
;
insert_node_in_freelist
(
root
,
new_block
);
}
return
(
void
*
)(
meta_data_block
+
1
);
}
}
else
{
uint32_t
req_rem_size
=
size
-
meta_data_block
->
block_size
;
uint32_t
inter_frag
=
0
;
if
(
meta_data_block
->
next_block
)
inter_frag
=
get_internal_fragmented_size
(
meta_data_block
,
meta_data_block
->
next_block
);
else
inter_frag
=
(
uint32_t
)((
char
*
)
mem_heap_hi
()
+
1
-
((
char
*
)
end_meta_data_addr
(
meta_data_block
)
+
sizeof
(
block_end_meta_data_t
)));
if
(
req_rem_size
<=
inter_frag
)
{
// TODO check sizeof function once
meta_data_block
->
block_size
+=
req_rem_size
;
block_end_meta_data_t
*
end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
meta_data_block
);
end_meta_data_block
->
block_size
=
meta_data_block
->
block_size
;
return
(
void
*
)(
meta_data_block
+
1
);
// Not handling adding remaining free part to free list because it is small in size to handle even headers, so skkipping.
}
if
(
meta_data_block
->
next_block
&&
meta_data_block
->
next_block
->
is_free
==
MM_TRUE
&&
\
req_rem_size
<=
(
TOTAL_COMBINE_SIZE_OF_BLOCKS
(
meta_data_block
->
next_block
)
+
inter_frag
))
{
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
&&
\
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
);
meta_data_block
->
prev_block
->
block_size
+=
req_rem_size
;
req_rem_size
-=
inter_frag
;
uint32_t
final_remain
=
abs
(
TOTAL_COMBINE_SIZE_OF_BLOCKS
(
meta_data_block
->
prev_block
)
-
req_rem_size
);
memcpy
((
char
*
)(
meta_data_block
->
prev_block
+
1
),
(
char
*
)(
meta_data_block
+
1
),
meta_data_block
->
block_size
);
block_end_meta_data_t
*
end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
meta_data_block
);
end_meta_data_block
->
block_size
=
meta_data_block
->
block_size
;
meta_data_block
=
meta_data_block
->
prev_block
;
if
(
final_remain
>
META_DATA_OVERHEAD
)
create_new_block_and_insert_into_freelist
(
meta_data_block
,
meta_data_block
->
next_block
,
final_remain
,
1
);
return
(
void
*
)(
meta_data_block
+
1
);
}
if
(
meta_data_block
->
next_block
&&
meta_data_block
->
next_block
->
is_free
&&
meta_data_block
->
prev_block
&&
meta_data_block
->
prev_block
->
is_free
&&
\
req_rem_size
<=
TOTAL_COMBINED_SIZE_OF_BLOCKS
(
meta_data_block
)
+
inter_frag
)
{
remove_block_from_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
)
sizeof
(
block_end_meta_data_t
)
\
+
(
uint32_t
)
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
);
block_end_meta_data_t
*
end_meta_data_block
=
(
block_end_meta_data_t
*
)
end_meta_data_addr
(
meta_data_block
);
end_meta_data_block
->
block_size
=
meta_data_block
->
block_size
;
meta_data_block
=
meta_data_block
->
prev_block
;
if
(
final_remain
>
META_DATA_OVERHEAD
)
create_new_block_and_insert_into_freelist
(
meta_data_block
,
meta_data_block
->
next_block
,
final_remain
,
0
);
return
(
void
*
)(
meta_data_block
+
1
);
}
void
*
ptr
=
mm_malloc
(
size
);
block_meta_data_t
*
new_meta_data_block
=
(
block_meta_data_t
*
)((
char
*
)
ptr
-
sizeof
(
block_meta_data_t
));
uint32_t
amount_to_be_copied
=
meta_data_block
->
block_size
;
memcpy
((
char
*
)(
new_meta_data_block
+
1
),
(
char
*
)(
meta_data_block
+
1
),
amount_to_be_copied
);
mm_free
((
void
*
)(
meta_data_block
+
1
));
return
(
void
*
)(
new_meta_data_block
+
1
);
}
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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment