-
Notifications
You must be signed in to change notification settings - Fork 0
/
memoryManager.c
153 lines (136 loc) · 4.12 KB
/
memoryManager.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include<stdio.h>
#include<unistd.h>
#include<stdbool.h>
#include<stdlib.h>
#include <math.h>
struct block
{
int block_size;
int start_index;
bool used;
struct block* next;
};
struct block* initialize(int initial_size)
{
struct block* head=(struct block*)malloc(sizeof(struct block));
head->block_size=initial_size;
head->start_index=0;
head->used=false;
head->next=NULL;
return head;
}
struct block* allocate_process(struct block* head,int mem_size)
{
mem_size=pow(2, ceil(log2(mem_size))); //round up to the first power of 2
struct block* iter=head;
struct block* min_block=head;
while(iter) //search for min sufficient block
{
if(!iter->used)
{
if((iter->block_size>mem_size&&iter->block_size<min_block->block_size )|| min_block->used || min_block->block_size<mem_size)
min_block=iter;
if(iter->block_size==mem_size && !iter->used)
{
min_block=iter;
break;
}
}
iter=iter->next;
}
if(min_block->used || min_block->block_size < mem_size) return NULL; //if no free block found
if(min_block->block_size==mem_size) //if no splitting required
{
min_block->used=true;
return min_block;
}
while(min_block->block_size>mem_size) //split till block size=rounded up mem size
{
int bSize=min_block->block_size;
int sIndex=min_block->start_index+(bSize/2);
struct block* new_block=(struct block*)malloc(sizeof(struct block));
new_block->used=false;
new_block->block_size=bSize/2;
new_block->start_index=sIndex;
new_block->next=min_block->next;
min_block->next=new_block;
min_block->block_size=bSize/2;
}
min_block->used=true;
return min_block;
}
int find_buddy(int addr,int size)
{
return addr ^ size;
}
bool deallocate_process(struct block* head,int index)
{
struct block* iter=head;
while(iter) //search for memory //can be removed if block* is passed to function
{
if(iter->start_index==index)
{
iter->used=false;
printf("Deallocated block at index %d, size %d\n", iter->start_index, iter->block_size);
break;
}
iter=iter->next;
}
bool merge=true;
while(merge)
{
merge=false;
iter=head;
while(iter)
{
if(!iter->used)
{
int buddy=find_buddy(iter->start_index,iter->block_size);
if(iter->next&&iter->next->start_index==buddy&&!iter->next->used && iter->block_size==iter->next->block_size)
{
//merge
struct block* temp=iter->next;
iter->block_size=iter->block_size*2;
iter->next=iter->next->next;
free(temp);
merge=true;
}
}
iter=iter->next;
}
}
}
void display_free_list(struct block* head) {
struct block* iter = head;
printf("Free List:\n");
while (iter) {
printf("Block at index %d, size %d, ", iter->start_index, iter->block_size);
if (iter->used) {
printf("used\n");
} else {
printf("unused\n");
}
iter = iter->next;
}
}
int main() //only for testing
{
// Initialize the memory with an initial size of 64
struct block* head = initialize(1024);
// Allocate memory for processes
struct block* process1 = allocate_process(head, 8);
struct block* process2 = allocate_process(head, 8);
struct block* process3 = allocate_process(head, 8);
struct block* process7 = allocate_process(head, 8);
struct block* process4 = allocate_process(head, 1024);
display_free_list(head);
deallocate_process(head, 8);
deallocate_process(head, 16);
display_free_list(head);
struct block* process5 = allocate_process(head, 1024);
display_free_list(head);
// Display the status of the free list after allocation
//display_free_list(head);
// Display the status of the free list after deallocation
//display_free_list(head);
}