Browse Source

Added more unallocation code

Thomas Johnson 1 year ago
parent
commit
7a8639902f
1 changed files with 44 additions and 1 deletions
  1. 44
    1
      tree_alloc.c

+ 44
- 1
tree_alloc.c View File

@@ -111,11 +111,54 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before)
111 111
   to_insert->parent = before;
112 112
 }
113 113
 
114
-void *unalloc(Arena *arena, void *addr) {
114
+void unalloc(Arena *arena, void *addr) {
115 115
   if (arena->root_treealloc == NULL) {
116 116
     arena->error("attempt to unallocate when there are no allocations!");
117
+    return;
117 118
   }
119
+  // Find the node this address belongs to
118 120
   TreeAlloc *node = search_by_address(arena->root_treealloc, addr);
121
+  if (node == NULL) {
122
+    arena->error("attempt to free memory outside any allocations!");
123
+    return;
124
+  }
125
+  // Handle the watermark allocator in this region
126
+  if (node->type == RT_WATERMARK) {
127
+    // TODO: handle watermark deallocation
128
+    return;
129
+  }
130
+  // Get rid of it
131
+  remove_node(&arena->root_treealloc, node);
132
+  // If there's free space on either side of it, merge it with the free space into a bigger chunk of
133
+  // free space.
134
+  uintptr_t size = node->size;
135
+  FreeSpace *start = (FreeSpace*) node;
136
+  if (node->before != NULL && node->before->type == RT_FREESPACE) {
137
+    start = (FreeSpace*) node->before;
138
+    size += node->before->size;
139
+    remove_node((TreeAlloc**) &arena->root_freespace, node->before);
140
+  }
141
+  if (node->after != NULL && node->after->type == RT_FREESPACE) {
142
+    size += node->after->size;
143
+    remove_node((TreeAlloc**) &arena->root_freespace, node->after);
144
+  }
145
+  start->type = RT_FREESPACE;
146
+  start->size = size;
147
+  // And finally, insert the resulting free space.
148
+  if (arena->root_freespace == NULL) {
149
+    insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start);
150
+  } else {
151
+    TreeAlloc *insert_point = search_by_size((TreeAlloc*) arena->root_freespace, 0, 1, size);
152
+    if (insert_point == NULL) {
153
+      TreeAlloc *head = (TreeAlloc*) arena->root_freespace;
154
+      while (head->right != NULL) {
155
+        head = head->right;
156
+      }
157
+      insert_right((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, head);
158
+    } else {
159
+      insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, insert_point);
160
+    }
161
+  }
119 162
   // TODO
120 163
 }
121 164
 

Loading…
Cancel
Save