-
Notifications
You must be signed in to change notification settings - Fork 0
/
mm_alloc.c
125 lines (108 loc) · 2.35 KB
/
mm_alloc.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
/*
* mm_alloc.c
*
* Stub implementations of the mm_* routines. Remove this comment and provide
* a summary of your allocator's design here.
*/
#include "mm_alloc.h"
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
/* Your final implementation should comment out this macro. */
void *zee = NULL;
struct nca {
size_t size;
bool free;
struct nca* next;
struct nca* prev;
};
#define BAR_SIZE sizeof(struct nca)
struct nca* nca2 (struct nca *prev, size_t size){
struct nca *newNca;
newNca = sbrk(0);
sbrk(size+BAR_SIZE);
if (prev){
prev->next=newNca;
newNca->prev=prev;
}
newNca->size = size;
newNca->next = NULL;
newNca->free = false;
return newNca;
}
struct block* splitBlock(struct nca* nca1, size_t size){
if (nca1->size>=1+size+BAR_SIZE){
struct nca * zwide = (struct nca *)((char*)nca1+BAR_SIZE+size);
zwide->size = nca1->size-(size+BAR_SIZE);
zwide->free=true;
zwide->next=nca1->next;
zwide->prev=nca1;
if (nca1->next){
nca1->next->prev=zwide;
}
nca1->size=size;
nca1->next = zwide;
}
return nca1;
}
struct nca* Free(struct nca *prev, size_t size){
struct nca *thisnca = zee;
while (true){
if (!thisnca){
return nca2(prev ,size);
}
if (thisnca&&thisnca->free && (thisnca->size)>=size){
thisnca=splitBlock(thisnca,size);
thisnca->free=false;
return thisnca;
}
prev = thisnca;
thisnca = thisnca->next;
}
return 0;
}
void merge(struct nca *thisnca){
if (thisnca->next){
if (thisnca->next->free){
thisnca->size+=thisnca->next->size+BAR_SIZE;
if (thisnca->next->next){
thisnca->next->next->prev=thisnca;
thisnca->next=thisnca->next->next;
}
}
}
if (thisnca->prev){
if (thisnca->prev->free){
merge(thisnca->prev);
}
}
}
void* mm_malloc(size_t size)
{
struct nca* newNca;
if (zee){
struct nca* finalnca=zee;
newNca=Free(finalnca, size);
}else{
newNca=nca2(NULL,size);
zee=newNca;
}
return (void*) ((long) newNca+BAR_SIZE);
}
void* mm_realloc(void* ptr, size_t size)
{
void *newNcaPtr = mm_malloc(size);
struct nca* prevnca = (struct nca*) ptr - 1;
memcpy(newNcaPtr, ptr, prevnca->size);
mm_free(ptr);
return newNcaPtr;
}
void mm_free(void* ptr)
{
struct nca* thisnca = (struct nca*) ptr - 1;
thisnca->free=true;
merge(thisnca);
}