Browse Source

Thick refactor in attempt to fix things

Cameron Weinfurt 5 months ago
parent
commit
ac2bc19ef1
2 changed files with 406 additions and 399 deletions
  1. 1
    0
      Makefile
  2. 405
    399
      tree_alloc.c

+ 1
- 0
Makefile View File

@@ -6,6 +6,7 @@ OUT_NAME = the_alloc
6 6
 
7 7
 dev: CFLAGS= $(COMMON_FLAGS) -g -D UNIT_TESTS -D DEBUG=1
8 8
 dev: $(OUT_NAME)
9
+	rm -f vgcore.*
9 10
 	valgrind ./$(OUT_NAME)
10 11
 
11 12
 release: CFLAGS= $(COMMON_FLAGS) -O2

+ 405
- 399
tree_alloc.c View File

@@ -8,28 +8,28 @@
8 8
 #include <stdio.h>
9 9
 
10 10
 int debug_tree_black_height(TreeAlloc *node) {
11
-  if (node == NULL) {
12
-    return 1;
13
-  }
14
-  return ((node->color == COLOR_BLACK) ? 1 : 0) + debug_tree_black_height(node->left);
11
+	if (node == NULL) {
12
+		return 1;
13
+	}
14
+	return ((node->color == COLOR_BLACK) ? 1 : 0) + debug_tree_black_height(node->left);
15 15
 }
16 16
 
17 17
 void debug_print_tree(int indent, void *p) {
18
-  TreeAlloc *node = (TreeAlloc*) p;
19
-  if (node != NULL) {
20
-    int bad = debug_tree_black_height(node->left) != debug_tree_black_height(node->right);
21
-    bad |= node->color == COLOR_RED && ((node->left != NULL && node->left->color == COLOR_RED) ||
22
-        (node->right != NULL && node->right->color == COLOR_RED) || (node->parent != NULL &&
23
-          node->parent->color == COLOR_RED));
24
-    debug_print_tree(indent + 1, node->left);
25
-    for (int ii = 0; ii < indent; ii++) { printf("  "); }
26
-    if (node->color == COLOR_RED) { printf(bad ? "\e[30m]" : "\e[31m"); }
27
-    if (bad) { printf("\e[43m"); }
28
-    printf("%p %lu\n", node, node->size);
29
-    if (node->color == COLOR_RED) { printf("\e[37m"); }
30
-    if (bad) { printf("\e[40m"); }
31
-    debug_print_tree(indent + 1, node->right);
32
-  }
18
+	TreeAlloc *node = (TreeAlloc*) p;
19
+	if (node != NULL) {
20
+		int bad = debug_tree_black_height(node->left) != debug_tree_black_height(node->right);
21
+		bad |= node->color == COLOR_RED && ((node->left != NULL && node->left->color == COLOR_RED) ||
22
+				(node->right != NULL && node->right->color == COLOR_RED) || (node->parent != NULL &&
23
+					node->parent->color == COLOR_RED));
24
+		debug_print_tree(indent + 1, node->left);
25
+		for (int ii = 0; ii < indent; ii++) { printf("  "); }
26
+		if (node->color == COLOR_RED) { printf(bad ? "\e[30m]" : "\e[31m"); }
27
+		if (bad) { printf("\e[43m"); }
28
+		printf("%p %lu\n", node, node->size);
29
+		if (node->color == COLOR_RED) { printf("\e[37m"); }
30
+		if (bad) { printf("\e[40m"); }
31
+		debug_print_tree(indent + 1, node->right);
32
+	}
33 33
 }
34 34
 
35 35
 #endif
@@ -42,26 +42,26 @@ TreeAlloc *insert_node_at(void *address, uintptr_t padding, uintptr_t align, uin
42 42
  * Search for the node whose allocated region contains an address.
43 43
  */
44 44
 TreeAlloc *search_by_address(TreeAlloc *root, void *address) {
45
-  TreeAlloc *head = root;
46
-  while (1) {
47
-    if (head > (TreeAlloc*) address) {
48
-      if (head->left == NULL) {
49
-        return NULL;
50
-      } else {
51
-        head = head->left;
52
-      }
53
-    } else {
54
-      if (head->right == NULL || head->right > (TreeAlloc*) address) {
55
-        return head;
56
-      } else {
57
-        head = head->right;
58
-      }
59
-    }
60
-  }
45
+	TreeAlloc *head = root;
46
+	while (1) {
47
+		if (head > (TreeAlloc*) address) {
48
+			if (head->left == NULL) {
49
+				return NULL;
50
+			} else {
51
+				head = head->left;
52
+			}
53
+		} else {
54
+			if (head->right == NULL || head->right > (TreeAlloc*) address) {
55
+				return head;
56
+			} else {
57
+				head = head->right;
58
+			}
59
+		}
60
+	}
61 61
 }
62 62
 
63 63
 static uintptr_t effective_size(TreeAlloc *head, uintptr_t padding, uintptr_t align) {
64
-    return head->size - (align_after(head + padding, align) - (void*) head);
64
+	return head->size - (align_after(head + padding, align) - (void*) head);
65 65
 }
66 66
 
67 67
 /* 
@@ -70,55 +70,55 @@ static uintptr_t effective_size(TreeAlloc *head, uintptr_t padding, uintptr_t al
70 70
  * ordering.
71 71
  */
72 72
 static uintptr_t pessimistic_size(TreeAlloc *head, uintptr_t padding, uintptr_t align) {
73
-    return head->size - padding - align + 1;
73
+	return head->size - padding - align + 1;
74 74
 }
75 75
 
76 76
 TreeAlloc *search_by_size(TreeAlloc *root, uintptr_t padding, uintptr_t align, uintptr_t size) {
77
-  TreeAlloc *head = root;
78
-  while (1) {
79
-    uintptr_t esize = pessimistic_size(head, padding, align);
80
-    if (esize < size) {
81
-      if (head->right == NULL) {
82
-        return NULL;
83
-      } else {
84
-        head = head->right;
85
-      }
86
-    } else {
87
-      if (head->left == NULL || pessimistic_size(head->left, padding, align) < size) {
88
-        return head;
89
-      } else {
90
-        head = head->left;
91
-      }
92
-    }
93
-  }
77
+	TreeAlloc *head = root;
78
+	while (1) {
79
+		uintptr_t esize = pessimistic_size(head, padding, align);
80
+		if (esize < size) {
81
+			if (head->right == NULL) {
82
+				return NULL;
83
+			} else {
84
+				head = head->right;
85
+			}
86
+		} else {
87
+			if (head->left == NULL || pessimistic_size(head->left, padding, align) < size) {
88
+				return head;
89
+			} else {
90
+				head = head->left;
91
+			}
92
+		}
93
+	}
94 94
 }
95 95
 
96 96
 TreeAlloc *succ(TreeAlloc *el) {
97
-  if (el->right != NULL) {
98
-    el = el->right;
99
-    while (el->left != NULL) {
100
-      el = el->left;
101
-    }
102
-    return el;
103
-  }
104
-  while (el->parent != NULL && el == el->parent->right) {
105
-    el = el->parent;
106
-  }
107
-  return el->parent;
97
+	if (el->right != NULL) {
98
+		el = el->right;
99
+		while (el->left != NULL) {
100
+			el = el->left;
101
+		}
102
+		return el;
103
+	}
104
+	while (el->parent != NULL && el == el->parent->right) {
105
+		el = el->parent;
106
+	}
107
+	return el->parent;
108 108
 }
109 109
 
110 110
 TreeAlloc *pred(TreeAlloc *el) {
111
-  if (el->left != NULL) {
112
-    el = el->left;
113
-    while (el->right != NULL) {
114
-      el = el->right;
115
-    }
116
-    return el;
117
-  }
118
-  while (el->parent != NULL && el == el->parent->left) {
119
-    el = el->parent;
120
-  }
121
-  return el->parent;
111
+	if (el->left != NULL) {
112
+		el = el->left;
113
+		while (el->right != NULL) {
114
+			el = el->right;
115
+		}
116
+		return el;
117
+	}
118
+	while (el->parent != NULL && el == el->parent->left) {
119
+		el = el->parent;
120
+	}
121
+	return el->parent;
122 122
 }
123 123
 
124 124
 TreeAlloc *get_sibling(TreeAlloc *ta) {
@@ -132,51 +132,47 @@ TreeAlloc *get_sibling(TreeAlloc *ta) {
132 132
 }
133 133
 
134 134
 void rotate_left(TreeAlloc **root_ptr, TreeAlloc *ta) {
135
-  TreeAlloc *parent, *tmp;
136
-
137
-  parent = ta->parent;
138
-  tmp = ta->right;
139
-  if (!tmp) return;
140
-
141
-  ta->right = tmp->left;
142
-  tmp->left = ta;
143
-  ta->parent = tmp;
144
-
145
-  if (ta->right) ta->right->parent = ta;
146
-
147
-  if (parent == NULL) {
148
-    *root_ptr = tmp;
149
-  } else {
150
-    if (ta == parent->left)
151
-      parent->left = tmp;
152
-    else
153
-      parent->right = tmp;
154
-  }
155
-  tmp->parent = parent;
135
+	TreeAlloc *parent, *tmp;
136
+
137
+	tmp = ta->right;
138
+	parent = ta->parent;
139
+
140
+	ta->right = tmp->left;
141
+	if (ta->right) ta->right->parent = ta;
142
+
143
+	tmp->left = ta;
144
+	ta->parent = tmp;
145
+	tmp->parent = parent;
146
+
147
+	if (!parent) {
148
+		*root_ptr = tmp;
149
+	} else if (ta == parent->left) {
150
+		parent->left = tmp;
151
+	} else {
152
+		parent->right = tmp;
153
+	}
156 154
 }
157 155
 
158 156
 void rotate_right(TreeAlloc **root_ptr, TreeAlloc *ta) {
159
-  TreeAlloc *parent, *tmp;
160
-
161
-  parent = ta->parent;
162
-  tmp = ta->left;
163
-  if (!tmp) return;
164
-
165
-  ta->left = tmp->right;
166
-  tmp->right = ta;
167
-  ta->parent = tmp;
168
-
169
-  if (ta->left) ta->left->parent = ta;
170
-
171
-  if (parent == NULL) {
172
-    *root_ptr = tmp;
173
-  } else {
174
-    if (ta == parent->left)
175
-      parent->left = tmp;
176
-    else
177
-      parent->right = tmp;
178
-  }
179
-  tmp->parent = parent;
157
+	TreeAlloc *parent, *tmp;
158
+
159
+	tmp = ta->left;
160
+	parent = ta->parent;
161
+
162
+	ta->left = tmp->right;
163
+	if (ta->left) ta->left->parent = ta;
164
+
165
+	tmp->right = ta;
166
+	ta->parent = tmp;
167
+	tmp->parent = parent;
168
+
169
+	if (!parent) {
170
+		*root_ptr = tmp;
171
+	} else if (ta == parent->left) {
172
+		parent->left = tmp;
173
+	} else {
174
+		parent->right = tmp;
175
+	}
180 176
 }
181 177
 
182 178
 #define IS_BLACK_NODE(n) (n == NULL || n->color == COLOR_BLACK)
@@ -185,51 +181,115 @@ void rotate_right(TreeAlloc **root_ptr, TreeAlloc *ta) {
185 181
 void repair_tree_after_insert(TreeAlloc **root_ptr, TreeAlloc *ta) {
186 182
 	TreeAlloc *parent = ta->parent;
187 183
 #ifdef DEBUG
188
-      printf("=== PRE-INSERT-FIXUP ===\n");
189
-      printf("===== CURRENT TREE =====\n");
190
-      debug_print_tree(0, *root_ptr);
191
-      printf("===== END OF TREES =====\n");
184
+	printf("=== PRE-INSERT-FIXUP ===\n");
185
+	printf("===== CURRENT TREE =====\n");
186
+	debug_print_tree(0, *root_ptr);
187
+	printf("===== END OF TREES =====\n");
192 188
 #endif
193 189
 
194
-	if (parent == NULL) {
190
+	if (ta == *root_ptr) {
195 191
 		ta->color = COLOR_BLACK;
192
+	} else if (IS_BLACK_NODE(parent)) {
196 193
 		return;
197
-	}
198
-	TreeAlloc *grandparent = parent->parent;
199
-	TreeAlloc *uncle = get_sibling(parent);
194
+	} else {
195
+		TreeAlloc *uncle = get_sibling(parent);
196
+		TreeAlloc *grandparent = parent->parent;
200 197
 
201
-	if (IS_RED_NODE(parent)) {
202 198
 		if (IS_RED_NODE(uncle)) {
203 199
 			parent->color = COLOR_BLACK;
204 200
 			uncle->color = COLOR_BLACK;
205
-			grandparent->color = COLOR_RED;
201
+			grandparent->color = COLOR_RED; 
206 202
 			repair_tree_after_insert(root_ptr, grandparent);
207 203
 		} else {
208
-			if (ta == parent->left && parent == grandparent->left) {
209
-				rotate_left(root_ptr, parent);
210
-				ta = ta->left;
211
-				parent = parent->left;
204
+			if (parent->left == ta) {
205
+				if (grandparent->left == parent) {
206
+					rotate_right(root_ptr, grandparent);
207
+					grandparent->color = COLOR_RED;
208
+					parent->color = COLOR_BLACK;
209
+				} else {
210
+					rotate_right(root_ptr, parent);
211
+					rotate_left(root_ptr, grandparent);
212
+					grandparent->color = COLOR_RED;
213
+					ta->color = COLOR_BLACK;
214
+				}
212 215
 			} else {
213
-				rotate_right(root_ptr, parent);
214
-				ta = ta->right;	
215
-				parent = parent->right;
216
+				if (grandparent->left == parent) {
217
+					rotate_left(root_ptr, parent);
218
+					rotate_right(root_ptr, grandparent);
219
+					grandparent->color = COLOR_RED;
220
+					ta->color = COLOR_BLACK;
221
+				} else {
222
+					rotate_left(root_ptr, grandparent);
223
+					grandparent->color = COLOR_RED;
224
+					parent->color = COLOR_BLACK;
225
+				}
216 226
 			}
217
-
218
-			grandparent = parent->parent;
219
-			if (ta == parent->left) {
220
-				rotate_right(root_ptr, grandparent);
221
-			} else {
222
-				rotate_left(root_ptr, grandparent);
223
-			}
224
-			parent->color = COLOR_BLACK;
225
-			grandparent->color = COLOR_RED;
226 227
 		}
227 228
 	}
229
+
230
+}
231
+// Inserts a node into an empty tree.
232
+void insert_singleton(TreeAlloc **root_ptr, TreeAlloc *to_insert) {
233
+#ifdef DEBUG
234
+	printf("= PRE-INSERT-SINGLETON =\n");
235
+	printf("===== CURRENT TREE =====\n");
236
+	debug_print_tree(0, *root_ptr);
237
+	printf("===== END OF TREES =====\n");
238
+#endif
239
+	*root_ptr = to_insert;
240
+	to_insert->parent = NULL;
241
+	to_insert->color = COLOR_BLACK;
242
+#ifdef DEBUG
243
+	printf("= POST-INSERT-SINGLETON =\n");
244
+	printf("===== CURRENT TREE =====\n");
245
+	debug_print_tree(0, *root_ptr);
246
+	printf("===== END OF TREES =====\n");
247
+#endif
248
+}
249
+
250
+void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after) {
251
+#ifdef DEBUG
252
+	printf("=== PRE-INSERT-RIGHT ===\n");
253
+	printf("===== CURRENT TREE =====\n");
254
+	debug_print_tree(0, *root_ptr);
255
+	printf("===== END OF TREES =====\n");
256
+#endif
257
+	if (after->right != NULL) {
258
+		after->right->parent = to_insert;
259
+		to_insert->right = after->right;
260
+	}
261
+	after->right = to_insert;
262
+	to_insert->parent = after;
263
+	to_insert->color = COLOR_RED;
264
+	repair_tree_after_insert(root_ptr, to_insert);
265
+#ifdef DEBUG
266
+	printf("== POST-INSERT-FIXUP ===\n");
267
+	printf("===== CURRENT TREE =====\n");
268
+	debug_print_tree(0, *root_ptr);
269
+	printf("===== END OF TREES =====\n");
270
+#endif
271
+}
272
+
273
+void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before) {
274
+#ifdef DEBUG
275
+	printf("=== PRE-INSERT-LEFT ====\n");
276
+	printf("===== CURRENT TREE =====\n");
277
+	debug_print_tree(0, *root_ptr);
278
+	printf("===== END OF TREES =====\n");
279
+#endif
280
+	if (before->left != NULL) {
281
+		before->left->parent = to_insert;
282
+		to_insert->left = before->left;
283
+	}
284
+	before->left = to_insert;
285
+	to_insert->parent = before;
286
+	to_insert->color = COLOR_RED;
287
+	repair_tree_after_insert(root_ptr, to_insert);
228 288
 #ifdef DEBUG
229
-      printf("== POST-INSERT-FIXUP ===\n");
230
-      printf("===== CURRENT TREE =====\n");
231
-      debug_print_tree(0, *root_ptr);
232
-      printf("===== END OF TREES =====\n");
289
+	printf("== POST-INSERT-FIXUP ===\n");
290
+	printf("===== CURRENT TREE =====\n");
291
+	debug_print_tree(0, *root_ptr);
292
+	printf("===== END OF TREES =====\n");
233 293
 #endif
234 294
 }
235 295
 
@@ -291,10 +351,10 @@ void repair_after_remove(TreeAlloc **root_ptr, TreeAlloc *node) {
291 351
 void remove_node(TreeAlloc **root_ptr, TreeAlloc *node) {
292 352
 	char do_repair = 0;
293 353
 #ifdef DEBUG
294
-      printf("====== PRE-REMOVE ======\n");
295
-      printf("===== CURRENT TREE =====\n");
296
-      debug_print_tree(0, *root_ptr);
297
-      printf("===== END OF TREES =====\n");
354
+	printf("====== PRE-REMOVE ======\n");
355
+	printf("===== CURRENT TREE =====\n");
356
+	debug_print_tree(0, *root_ptr);
357
+	printf("===== END OF TREES =====\n");
298 358
 #endif
299 359
 	TreeAlloc *replace;
300 360
 	TreeAlloc *parent = node->parent;
@@ -322,295 +382,241 @@ void remove_node(TreeAlloc **root_ptr, TreeAlloc *node) {
322 382
 		node->left->parent = tmp;
323 383
 	}
324 384
 
325
-  	// Make sure that it doesn't have any tree pointers it shouldn't have.
326
-  	node->parent = node->left = node->right = NULL;
385
+	// Make sure that it doesn't have any tree pointers it shouldn't have.
386
+	node->parent = node->left = node->right = NULL;
327 387
 
328 388
 	if (replace && replace->parent == NULL) {
329 389
 #ifdef DEBUG
330
-      printf("=== PRE-REMOVE-FIXUP ===\n");
331
-      printf("===== CURRENT TREE =====\n");
332
-      debug_print_tree(0, *root_ptr);
333
-      printf("===== END OF TREES =====\n");
390
+		printf("=== PRE-REMOVE-FIXUP ===\n");
391
+		printf("===== CURRENT TREE =====\n");
392
+		debug_print_tree(0, *root_ptr);
393
+		printf("===== END OF TREES =====\n");
334 394
 #endif
335
-	  replace->color = COLOR_BLACK;
395
+		replace->color = COLOR_BLACK;
336 396
 	} else if (do_repair && replace) {
337 397
 #ifdef DEBUG
338
-      printf("=== PRE-REMOVE-FIXUP ===\n");
339
-      printf("===== CURRENT TREE =====\n");
340
-      debug_print_tree(0, *root_ptr);
341
-      printf("===== END OF TREES =====\n");
398
+		printf("=== PRE-REMOVE-FIXUP ===\n");
399
+		printf("===== CURRENT TREE =====\n");
400
+		debug_print_tree(0, *root_ptr);
401
+		printf("===== END OF TREES =====\n");
342 402
 #endif
343 403
 		repair_after_remove(root_ptr, replace);
344 404
 	}
345 405
 #ifdef DEBUG
346
-      printf("=== POST-REMOVE ===\n");
347
-      printf("===== CURRENT TREE =====\n");
348
-      debug_print_tree(0, *root_ptr);
349
-      printf("===== END OF TREES =====\n");
350
-#endif
351
-}
352
-
353
-
354
-// Inserts a node into an empty tree.
355
-void insert_singleton(TreeAlloc **root_ptr, TreeAlloc *to_insert) {
356
-#ifdef DEBUG
357
-  printf("= PRE-INSERT-SINGLETON =\n");
358
-  printf("===== CURRENT TREE =====\n");
359
-  debug_print_tree(0, *root_ptr);
360
-  printf("===== END OF TREES =====\n");
361
-#endif
362
-  *root_ptr = to_insert;
363
-  to_insert->parent = NULL;
364
-  to_insert->color = COLOR_BLACK;
365
-#ifdef DEBUG
366
-  printf("= POST-INSERT-SINGLETON =\n");
367
-  printf("===== CURRENT TREE =====\n");
368
-  debug_print_tree(0, *root_ptr);
369
-  printf("===== END OF TREES =====\n");
370
-#endif
371
-}
372
-
373
-void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after) {
374
-#ifdef DEBUG
375
-  printf("=== PRE-INSERT-RIGHT ===\n");
376
-  printf("===== CURRENT TREE =====\n");
377
-  debug_print_tree(0, *root_ptr);
378
-  printf("===== END OF TREES =====\n");
406
+	printf("=== POST-REMOVE ===\n");
407
+	printf("===== CURRENT TREE =====\n");
408
+	debug_print_tree(0, *root_ptr);
409
+	printf("===== END OF TREES =====\n");
379 410
 #endif
380
-  if (after->right != NULL) {
381
-    after->right->parent = to_insert;
382
-    to_insert->right = after->right;
383
-  }
384
-  after->right = to_insert;
385
-  to_insert->parent = after;
386
-  to_insert->color = COLOR_RED;
387
-  repair_tree_after_insert(root_ptr, to_insert);
388
-}
389
-
390
-void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before) {
391
-#ifdef DEBUG
392
-  printf("=== PRE-INSERT-LEFT ====\n");
393
-  printf("===== CURRENT TREE =====\n");
394
-  debug_print_tree(0, *root_ptr);
395
-  printf("===== END OF TREES =====\n");
396
-#endif
397
-  if (before->left != NULL) {
398
-    before->left->parent = to_insert;
399
-    to_insert->left = before->left;
400
-  }
401
-  before->left = to_insert;
402
-  to_insert->parent = before;
403
-  to_insert->color = COLOR_RED;
404
-	repair_tree_after_insert(root_ptr, to_insert);
405 411
 }
406 412
 
407 413
 int add_new_region(Arena *arena, uintptr_t size, uintptr_t padding, uintptr_t align) {
408
-    uintptr_t realsize = size + align + alignof(WatermarkAlloc) + padding - 1;
409
-    if (realsize < MIN_NEW_MEM_SIZE) {
410
-      realsize = MIN_NEW_MEM_SIZE;
411
-    }
412
-    FreeSpace *reg = (FreeSpace*) arena->get_new_region(realsize);
413
-    if (reg == NULL) {
414
-      arena->error("can't allocate a new memory region!");
415
-      return 0;
416
-    }
417
-    FreeSpace *newreg = align_after(reg, alignof(WatermarkAlloc));
418
-    newreg->left = NULL;
419
-    newreg->right = NULL;
420
-    realsize -= (void*) newreg - (void*) reg;
421
-    realsize -= realsize % alignof(WatermarkAlloc);
422
-    newreg->size = realsize;
423
-    if (arena->root_freespace == NULL) {
424
-      insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) newreg);
425
-    } else {
426
-      FreeSpace *head = arena->root_freespace;
427
-      while (head->right != NULL) {
428
-        head = head->right;
429
-      }
430
-      insert_right((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) newreg, (TreeAlloc*) head);
431
-    }
414
+	uintptr_t realsize = size + align + alignof(WatermarkAlloc) + padding - 1;
415
+	if (realsize < MIN_NEW_MEM_SIZE) {
416
+		realsize = MIN_NEW_MEM_SIZE;
417
+	}
418
+	FreeSpace *reg = (FreeSpace*) arena->get_new_region(realsize);
419
+	if (reg == NULL) {
420
+		arena->error("can't allocate a new memory region!");
421
+		return 0;
422
+	}
423
+	FreeSpace *newreg = align_after(reg, alignof(WatermarkAlloc));
424
+	newreg->left = NULL;
425
+	newreg->right = NULL;
426
+	realsize -= (void*) newreg - (void*) reg;
427
+	realsize -= realsize % alignof(WatermarkAlloc);
428
+	newreg->size = realsize;
429
+	if (arena->root_freespace == NULL) {
430
+		insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) newreg);
431
+	} else {
432
+		FreeSpace *head = arena->root_freespace;
433
+		while (head->right != NULL) {
434
+			head = head->right;
435
+		}
436
+		insert_right((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) newreg, (TreeAlloc*) head);
437
+	}
432 438
 #ifdef DEBUG
433
-    printf("= POST-REGION-CREATION =\n");
434
-    printf("==== FREESPACE TREE ====\n");
435
-    debug_print_tree(0, arena->root_freespace);
436
-    printf("==== TREEALLOC TREE ====\n");
437
-    debug_print_tree(0, arena->root_treealloc);
438
-    printf("===== END OF TREES =====\n");
439
+	printf("= POST-REGION-CREATION =\n");
440
+	printf("==== FREESPACE TREE ====\n");
441
+	debug_print_tree(0, arena->root_freespace);
442
+	printf("==== TREEALLOC TREE ====\n");
443
+	debug_print_tree(0, arena->root_treealloc);
444
+	printf("===== END OF TREES =====\n");
439 445
 #endif
440
-    return 1;
446
+	return 1;
441 447
 }
442 448
 
443 449
 void unalloc(Arena *arena, void *addr) {
444 450
 #ifdef DEBUG
445
-  printf("==== UNALLOCATING ====\n");
446
-  printf("=== FREESPACE TREE ===\n");
447
-  debug_print_tree(0, arena->root_freespace);
448
-  printf("=== TREEALLOC TREE ===\n");
449
-  debug_print_tree(0, arena->root_treealloc);
450
-  printf("==== END OF TREES ====\n");
451
+	printf("==== UNALLOCATING ====\n");
452
+	printf("=== FREESPACE TREE ===\n");
453
+	debug_print_tree(0, arena->root_freespace);
454
+	printf("=== TREEALLOC TREE ===\n");
455
+	debug_print_tree(0, arena->root_treealloc);
456
+	printf("==== END OF TREES ====\n");
451 457
 #endif
452
-  if (arena->root_treealloc == NULL) {
453
-    arena->error("attempt to unallocate when there are no allocations!");
454
-    return;
455
-  }
456
-  // Find the node this address belongs to
457
-  TreeAlloc *node = search_by_address(arena->root_treealloc, addr);
458
-  if (node == NULL) {
459
-    arena->error("attempt to free memory outside any allocations!");
460
-    return;
461
-  }
462
-  // Handle the watermark allocator in this region
463
-  if (node->type == RT_WATERMARK) {
464
-    // TODO: handle watermark deallocation
465
-    return;
466
-  }
467
-  // Get rid of it
468
-  remove_node(&arena->root_treealloc, node);
469
-  // If there's free space on either side of it, merge it with the free space into a bigger chunk of
470
-  // free space.
471
-  uintptr_t size = node->size;
472
-  FreeSpace *start = (FreeSpace*) node;
473
-  if (node->before != NULL && node->before->type == RT_FREESPACE) {
474
-    start = (FreeSpace*) node->before;
475
-    size += node->before->size;
476
-    remove_node((TreeAlloc**) &arena->root_freespace, node->before);
477
-  }
478
-  if (node->after != NULL && node->after->type == RT_FREESPACE) {
479
-    size += node->after->size;
480
-    remove_node((TreeAlloc**) &arena->root_freespace, node->after);
481
-  }
482
-  start->type = RT_FREESPACE;
483
-  start->size = size;
484
-  // And finally, insert the resulting free space.
485
-  if (arena->root_freespace == NULL) {
486
-    insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start);
487
-  } else {
488
-    TreeAlloc *insert_point = search_by_size((TreeAlloc*) arena->root_freespace, 0, 1, size);
489
-    if (insert_point == NULL) {
490
-      TreeAlloc *head = (TreeAlloc*) arena->root_freespace;
491
-      while (head->right != NULL) {
492
-        head = head->right;
493
-      }
494
-      insert_right((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, head);
495
-    } else {
496
-      insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, insert_point);
497
-    }
498
-  }
458
+	if (arena->root_treealloc == NULL) {
459
+		arena->error("attempt to unallocate when there are no allocations!");
460
+		return;
461
+	}
462
+	// Find the node this address belongs to
463
+	TreeAlloc *node = search_by_address(arena->root_treealloc, addr);
464
+	if (node == NULL) {
465
+		arena->error("attempt to free memory outside any allocations!");
466
+		return;
467
+	}
468
+	// Handle the watermark allocator in this region
469
+	if (node->type == RT_WATERMARK) {
470
+		// TODO: handle watermark deallocation
471
+		return;
472
+	}
473
+	// Get rid of it
474
+	remove_node(&arena->root_treealloc, node);
475
+	// If there's free space on either side of it, merge it with the free space into a bigger chunk of
476
+	// free space.
477
+	uintptr_t size = node->size;
478
+	FreeSpace *start = (FreeSpace*) node;
479
+	if (node->before != NULL && node->before->type == RT_FREESPACE) {
480
+		start = (FreeSpace*) node->before;
481
+		size += node->before->size;
482
+		remove_node((TreeAlloc**) &arena->root_freespace, node->before);
483
+	}
484
+	if (node->after != NULL && node->after->type == RT_FREESPACE) {
485
+		size += node->after->size;
486
+		remove_node((TreeAlloc**) &arena->root_freespace, node->after);
487
+	}
488
+	start->type = RT_FREESPACE;
489
+	start->size = size;
490
+	// And finally, insert the resulting free space.
491
+	if (arena->root_freespace == NULL) {
492
+		insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start);
493
+	} else {
494
+		TreeAlloc *insert_point = search_by_size((TreeAlloc*) arena->root_freespace, 0, 1, size);
495
+		if (insert_point == NULL) {
496
+			TreeAlloc *head = (TreeAlloc*) arena->root_freespace;
497
+			while (head->right != NULL) {
498
+				head = head->right;
499
+			}
500
+			insert_right((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, head);
501
+		} else {
502
+			insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, insert_point);
503
+		}
504
+	}
499 505
 }
500 506
 
501 507
 void *alloc(Arena *arena, uintptr_t size, uintptr_t align) {
502
-  uintptr_t actual_align = lcm(alignof(struct WatermarkAlloc), align);
508
+	uintptr_t actual_align = lcm(alignof(struct WatermarkAlloc), align);
503 509
 #ifdef DEBUG
504
-  printf("==== ALLOCATING =====\n");
505
-  printf("=== FREESPACE TREE ===\n");
506
-  debug_print_tree(0, arena->root_freespace);
507
-  printf("=== TREEALLOC TREE ===\n");
508
-  debug_print_tree(0, arena->root_treealloc);
509
-  printf("==== END OF TREES ====\n");
510
+	printf("==== ALLOCATING =====\n");
511
+	printf("=== FREESPACE TREE ===\n");
512
+	debug_print_tree(0, arena->root_freespace);
513
+	printf("=== TREEALLOC TREE ===\n");
514
+	debug_print_tree(0, arena->root_treealloc);
515
+	printf("==== END OF TREES ====\n");
510 516
 #endif
511
-  if (arena->root_freespace == NULL) {
512
-    // Handle being out of freespace.
517
+	if (arena->root_freespace == NULL) {
518
+		// Handle being out of freespace.
513 519
 #ifdef DEBUG
514
-    printf("Out of freespace nodes; getting more\n");
520
+		printf("Out of freespace nodes; getting more\n");
515 521
 #endif
516
-    if (!add_new_region(arena, size, sizeof(TreeAlloc), actual_align)) {
517
-      return NULL;
518
-    }
519
-    return alloc(arena, size, align);
520
-  } else {
521
-    TreeAlloc *region = search_by_size((TreeAlloc*) arena->root_freespace, sizeof(TreeAlloc), actual_align, size);
522
-    if (region == NULL) {
523
-      // Handle insufficient freespace or fragmentation.
522
+		if (!add_new_region(arena, size, sizeof(TreeAlloc), actual_align)) {
523
+			return NULL;
524
+		}
525
+		return alloc(arena, size, align);
526
+	} else {
527
+		TreeAlloc *region = search_by_size((TreeAlloc*) arena->root_freespace, sizeof(TreeAlloc), actual_align, size);
528
+		if (region == NULL) {
529
+			// Handle insufficient freespace or fragmentation.
524 530
 #ifdef DEBUG
525
-      printf("Out of sufficiently large freespace nodes; getting more\n");
531
+			printf("Out of sufficiently large freespace nodes; getting more\n");
526 532
 #endif
527
-      if (!add_new_region(arena, size, sizeof(TreeAlloc), actual_align)) {
528
-        return NULL;
529
-      }
530
-      return alloc(arena, size, align);
531
-    }
532
-    remove_node((TreeAlloc**) &arena->root_freespace, region);
533
-    void *true_end = align_after(align_after(((void*) region) + sizeof(TreeAlloc), actual_align) + size, alignof(WatermarkAlloc));
534
-    // The size of the new allocation (adjusted for region header and alignment
535
-    uintptr_t new_size = true_end - (void*) region;
536
-    // The size of the free space region following the new allocation
537
-    uintptr_t new_free_size = region->size - new_size;
538
-    region->right = NULL;
539
-    region->left = NULL;
540
-    region->type = RT_TREE_NODE;
533
+			if (!add_new_region(arena, size, sizeof(TreeAlloc), actual_align)) {
534
+				return NULL;
535
+			}
536
+			return alloc(arena, size, align);
537
+		}
538
+		remove_node((TreeAlloc**) &arena->root_freespace, region);
539
+		void *true_end = align_after(align_after(((void*) region) + sizeof(TreeAlloc), actual_align) + size, alignof(WatermarkAlloc));
540
+		// The size of the new allocation (adjusted for region header and alignment
541
+		uintptr_t new_size = true_end - (void*) region;
542
+		// The size of the free space region following the new allocation
543
+		uintptr_t new_free_size = region->size - new_size;
544
+		region->right = NULL;
545
+		region->left = NULL;
546
+		region->type = RT_TREE_NODE;
541 547
 #ifdef DEBUG
542
-    printf("start: %p, end: %p, adjusted end: %p\n", region, ((void*) region) + size, true_end);
543
-    printf("size: %lu -> %lu\n", size, new_size);
548
+		printf("start: %p, end: %p, adjusted end: %p\n", region, ((void*) region) + size, true_end);
549
+		printf("size: %lu -> %lu\n", size, new_size);
544 550
 #endif
545
-    if (arena->root_treealloc == NULL) {
546
-      insert_singleton((TreeAlloc**) &arena->root_treealloc, region);
547
-    } else {
551
+		if (arena->root_treealloc == NULL) {
552
+			insert_singleton((TreeAlloc**) &arena->root_treealloc, region);
553
+		} else {
548 554
 #ifdef DEBUG
549
-      printf("searching for an insert point\n");
555
+			printf("searching for an insert point\n");
550 556
 #endif
551
-      TreeAlloc *insert_point = search_by_address((TreeAlloc*) arena->root_treealloc, region);
552
-      if (insert_point == NULL) {
553
-        TreeAlloc *head = arena->root_treealloc;
554
-        while (head->left != NULL) {
555
-          head = head->left;
556
-        }
557
+			TreeAlloc *insert_point = search_by_address((TreeAlloc*) arena->root_treealloc, region);
558
+			if (insert_point == NULL) {
559
+				TreeAlloc *head = arena->root_treealloc;
560
+				while (head->left != NULL) {
561
+					head = head->left;
562
+				}
557 563
 #ifdef DEBUG
558
-        printf("none found; inserting before %p\n", head);
564
+				printf("none found; inserting before %p\n", head);
559 565
 #endif
560
-        insert_left(&arena->root_treealloc, region, head);
561
-      } else {
566
+				insert_left(&arena->root_treealloc, region, head);
567
+			} else {
562 568
 #ifdef DEBUG
563
-        printf("found one: %p\n", insert_point);
569
+				printf("found one: %p\n", insert_point);
564 570
 #endif
565
-        insert_right(&arena->root_treealloc, region, insert_point);
566
-      }
567
-    }
568
-    if (new_free_size >= sizeof(FreeSpace)) {
569
-      // If there's enough free space after the allocation, use it!
570
-      region->size = new_size;  // Safe because the allocated region tree is not sorted by size.
571
-      FreeSpace *new_free = (FreeSpace*) ((void*) region + new_size);
572
-      new_free->left = NULL;
573
-      new_free->right = NULL;
574
-      new_free->type = RT_FREESPACE;
575
-      new_free->size = new_free_size;
576
-      if (arena->root_freespace == NULL) {
577
-        insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) new_free);
578
-      } else {
579
-        FreeSpace *insert_point = (FreeSpace*) search_by_size((TreeAlloc*) arena->root_freespace, 0, 1, new_free_size);
580
-        insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) new_free, (TreeAlloc*) insert_point);
581
-      }
582
-      // Set the region following this one to be the new free space
583
-      region->after = (TreeAlloc*) new_free;
584
-    } else {
585
-      // There isn't a free space after this one, so put the `next` pointer at the next allocated
586
-      // region.
587
-      region->after = succ(region);
588
-    }
589
-    // I seem to have forgotten about the fact that memory may not be contiguous
590
-    if (region->after != NULL && region->after != (void*) region + region->size) {
591
-      region->after = NULL;
592
-    }
593
-    // Also make sure the `before` pointer is correct.
594
-    TreeAlloc *before_alloc = pred(region);
595
-    if (before_alloc == NULL || ((void*) before_alloc) + before_alloc->size < (void*) region) {
596
-      region->before = search_by_address((TreeAlloc*) arena->root_freespace, region);
597
-    } else {
598
-      region->before = before_alloc;
599
-    }
600
-    // I seem to have forgotten about the fact that memory may not be contiguous
601
-    if (region->before != NULL && region->before != (void*) region->before + region->before->size) {
602
-      region->before = NULL;
603
-    }
571
+				insert_right(&arena->root_treealloc, region, insert_point);
572
+			}
573
+		}
574
+		if (new_free_size >= sizeof(FreeSpace)) {
575
+			// If there's enough free space after the allocation, use it!
576
+			region->size = new_size;  // Safe because the allocated region tree is not sorted by size.
577
+			FreeSpace *new_free = (FreeSpace*) ((void*) region + new_size);
578
+			new_free->left = NULL;
579
+			new_free->right = NULL;
580
+			new_free->type = RT_FREESPACE;
581
+			new_free->size = new_free_size;
582
+			if (arena->root_freespace == NULL) {
583
+				insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) new_free);
584
+			} else {
585
+				FreeSpace *insert_point = (FreeSpace*) search_by_size((TreeAlloc*) arena->root_freespace, 0, 1, new_free_size);
586
+				insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) new_free, (TreeAlloc*) insert_point);
587
+			}
588
+			// Set the region following this one to be the new free space
589
+			region->after = (TreeAlloc*) new_free;
590
+		} else {
591
+			// There isn't a free space after this one, so put the `next` pointer at the next allocated
592
+			// region.
593
+			region->after = succ(region);
594
+		}
595
+		// I seem to have forgotten about the fact that memory may not be contiguous
596
+		if (region->after != NULL && region->after != (void*) region + region->size) {
597
+			region->after = NULL;
598
+		}
599
+		// Also make sure the `before` pointer is correct.
600
+		TreeAlloc *before_alloc = pred(region);
601
+		if (before_alloc == NULL || ((void*) before_alloc) + before_alloc->size < (void*) region) {
602
+			region->before = search_by_address((TreeAlloc*) arena->root_freespace, region);
603
+		} else {
604
+			region->before = before_alloc;
605
+		}
606
+		// I seem to have forgotten about the fact that memory may not be contiguous
607
+		if (region->before != NULL && region->before != (void*) region->before + region->before->size) {
608
+			region->before = NULL;
609
+		}
604 610
 #ifdef DEBUG
605
-    printf("region is still at %p\n", region);
611
+		printf("region is still at %p\n", region);
606 612
 #endif
607
-    return align_after((void*) region + sizeof(TreeAlloc), actual_align);
608
-  }
613
+		return align_after((void*) region + sizeof(TreeAlloc), actual_align);
614
+	}
609 615
 }
610 616
 
611 617
 void *alloc_growable(Arena *arena, uintptr_t size, uintptr_t align) {
612
-  // TODO: Basically the same as above, but put the allocated region in the center of the largest free
613
-  // space. Due to alignment and whatnot, the code will be gory.
614
-  return NULL;
618
+	// TODO: Basically the same as above, but put the allocated region in the center of the largest free
619
+	// space. Due to alignment and whatnot, the code will be gory.
620
+	return NULL;
615 621
 }
616 622
 

Loading…
Cancel
Save