Browse Source

Merge branch 'tree_alloc' of gitea:cameron/cs241-project into tree_alloc

Thomas Johnson 1 year ago
parent
commit
915b82c51a
2 changed files with 111 additions and 7 deletions
  1. 6
    0
      allocator_internal.h
  2. 105
    7
      tree_alloc.c

+ 6
- 0
allocator_internal.h View File

@@ -8,6 +8,9 @@ const char RT_FREESPACE = 0;
8 8
 const char RT_TREE_NODE = 1;
9 9
 const char RT_WATERMARK = 2;
10 10
 
11
+const char COLOR_RED = 0;
12
+const char COLOR_BLACK = 1;
13
+
11 14
 typedef struct Arena {
12 15
   struct FreeSpace *root_freespace;
13 16
   struct TreeAlloc *root_treealloc;
@@ -25,6 +28,7 @@ typedef struct Arena {
25 28
 
26 29
 typedef struct TreeAlloc {
27 30
   char type;  // Should be RT_TREE_NODE
31
+  char color;
28 32
   struct TreeAlloc *parent;
29 33
   struct TreeAlloc *left;
30 34
   struct TreeAlloc *right;
@@ -35,6 +39,7 @@ typedef struct TreeAlloc {
35 39
 
36 40
 typedef struct FreeSpace {
37 41
   char type;  // Should be RT_FREESPACE
42
+  char color;
38 43
   struct FreeSpace *parent;
39 44
   struct FreeSpace *left;
40 45
   struct FreeSpace *right;
@@ -43,6 +48,7 @@ typedef struct FreeSpace {
43 48
 
44 49
 typedef struct WatermarkAlloc {
45 50
   char type;  // Should be RT_WATERMARK
51
+  char color;
46 52
   struct TreeAlloc *parent;
47 53
   struct TreeAlloc *left;
48 54
   struct TreeAlloc *right;

+ 105
- 7
tree_alloc.c View File

@@ -7,7 +7,9 @@ TreeAlloc *insert_node_at(void *address, uintptr_t padding, uintptr_t align, uin
7 7
 	return NULL;
8 8
 }
9 9
 
10
-// Search for the node whose allocated region contains an address.
10
+/*
11
+ * Search for the node whose allocated region contains an address.
12
+ */
11 13
 TreeAlloc *search_by_address(TreeAlloc *root, void *address) {
12 14
   TreeAlloc *head = root;
13 15
   while (1) {
@@ -31,9 +33,11 @@ static uintptr_t effective_size(TreeAlloc *head, uintptr_t padding, uintptr_t al
31 33
     return head->size - (align_after(head + padding, align) - (void*) head);
32 34
 }
33 35
 
34
-// This is the most optimistic estimate of size that we can use which also preserves the ordering over
35
-// the tree. I had planned to use effective_size before I realized that it would break the tree
36
-// ordering.
36
+/* 
37
+ * This is the most optimistic estimate of size that we can use which also preserves the ordering over
38
+ * the tree. I had planned to use effective_size before I realized that it would break the tree
39
+ * ordering.
40
+ */
37 41
 static uintptr_t pessimistic_size(TreeAlloc *head, uintptr_t padding, uintptr_t align) {
38 42
     return head->size - padding - align + 1;
39 43
 }
@@ -58,6 +62,99 @@ TreeAlloc *search_by_size(TreeAlloc *root, uintptr_t padding, uintptr_t align, u
58 62
   }
59 63
 }
60 64
 
65
+TreeAlloc *get_sibling(TreeAlloc *ta) {
66
+	TreeAlloc *p = ta->parent;
67
+	if (!p)
68
+		return NULL;
69
+	else if (p->left == ta)
70
+		return p->right;
71
+	else
72
+		return p->left;
73
+}
74
+
75
+void rotate_left(TreeAlloc *ta) {
76
+		TreeAlloc *parent, *tmp;
77
+		
78
+		parent = ta->parent;
79
+		tmp = ta->right;
80
+		if (!tmp) return;
81
+		
82
+		ta->right = tmp->left;
83
+		tmp->left = ta;
84
+		ta->parent = tmp;
85
+
86
+		if (ta->right) ta->right->parent = ta;
87
+
88
+		if (parent) {
89
+				if (ta == parent->left)
90
+						parent->left = tmp;
91
+				else
92
+						parent->right = tmp;
93
+		}
94
+		tmp->parent = parent;
95
+}
96
+
97
+void rotate_right(TreeAlloc *ta) {
98
+		TreeAlloc *parent, *tmp;
99
+		
100
+		parent = ta->parent;
101
+		tmp = ta->left;
102
+		if (!tmp) return;
103
+		
104
+		ta->left = tmp->right;
105
+		tmp->right = ta;
106
+		ta->parent = tmp;
107
+
108
+		if (ta->left) ta->left->parent = ta;
109
+
110
+		if (parent) {
111
+				if (ta == parent->left)
112
+						parent->left = tmp;
113
+				else
114
+						parent->right = tmp;
115
+		}
116
+		tmp->parent = parent;
117
+}
118
+
119
+void repair_tree_after_insert(TreeAlloc *ta) {
120
+	TreeAlloc *parent = ta->parent;
121
+	
122
+	if (parent == NULL) {
123
+		ta->color = COLOR_BLACK;
124
+		return;
125
+	}
126
+	
127
+	TreeAlloc *grandparent = parent->parent;
128
+	TreeAlloc *uncle = get_sibling(parent);
129
+
130
+	if (parent->color == COLOR_RED) {
131
+		if (uncle != NULL && uncle->color == COLOR_RED) {
132
+			parent->color = COLOR_BLACK;
133
+			uncle->color = COLOR_BLACK;
134
+			grandparent->color = COLOR_RED;
135
+			repair_tree_after_insert(grandparent);
136
+		} else {
137
+				if (ta == parent->left && parent == grandparent->left) {
138
+						rotate_left(parent);
139
+						ta = ta->left;
140
+				} else {
141
+						rotate_right(parent);
142
+						ta = ta->right;	
143
+				}
144
+
145
+				parent = ta->parent;
146
+				grandparent = parent->parent;
147
+				if (ta == parent->left) {
148
+						rotate_right(grandparent);
149
+				} else {
150
+						rotate_left(grandparent);
151
+				}
152
+				parent->color = COLOR_BLACK;
153
+				grandparent->color = COLOR_RED;
154
+		}
155
+	}
156
+}
157
+
61 158
 // TODO: Rewrite for self-balancing tree.
62 159
 void remove_node(TreeAlloc** root_ptr, TreeAlloc* node) {
63 160
   TreeAlloc *replace = NULL;
@@ -84,14 +181,14 @@ void remove_node(TreeAlloc** root_ptr, TreeAlloc* node) {
84 181
   }
85 182
 }
86 183
 
184
+
87 185
 // Inserts a node into an empty tree.
88
-// TODO: Rewrite for self-balancing tree.
89 186
 void insert_singleton(TreeAlloc **root_ptr, TreeAlloc *to_insert) {
90 187
   *root_ptr = to_insert;
91 188
   to_insert->parent = NULL;
189
+  repair_tree_after_insert(to_insert);
92 190
 }
93 191
 
94
-// TODO: Rewrite for self-balancing tree.
95 192
 void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after) {
96 193
   if (after->right != NULL) {
97 194
     after->right->parent = to_insert;
@@ -99,9 +196,9 @@ void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after)
99 196
   }
100 197
   after->right = to_insert;
101 198
   to_insert->parent = after;
199
+  repair_tree_after_insert(to_insert);
102 200
 }
103 201
 
104
-// TODO: Rewrite for self-balancing tree.
105 202
 void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before) {
106 203
   if (before->left != NULL) {
107 204
     before->left->parent = to_insert;
@@ -109,6 +206,7 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before)
109 206
   }
110 207
   before->left = to_insert;
111 208
   to_insert->parent = before;
209
+	repair_tree_after_insert(to_insert);
112 210
 }
113 211
 
114 212
 void unalloc(Arena *arena, void *addr) {

Loading…
Cancel
Save