summaryrefslogtreecommitdiff
path: root/src/memory/virtalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory/virtalloc.c')
-rw-r--r--src/memory/virtalloc.c106
1 files changed, 76 insertions, 30 deletions
diff --git a/src/memory/virtalloc.c b/src/memory/virtalloc.c
index baa7892..bfeb670 100644
--- a/src/memory/virtalloc.c
+++ b/src/memory/virtalloc.c
@@ -35,6 +35,32 @@ static struct addr_node *get_node_idx(int idx) {
}
}
+static void update_node_ptrs(
+ struct addr_node *old,
+ struct addr_node *new,
+ int old_len,
+ int new_len
+) {
+ if (old == NULL)
+ return;
+ int idx = 0;
+ for (int i = 0; i < old_len; i++) {
+ struct addr_node *o = &old[i];
+ if (o && !o->is_used)
+ continue;
+ struct addr_node *n = &new[idx++];
+ *n = *o;
+ if (n->prev != NULL)
+ n->prev->next = n;
+ if (n->next != NULL)
+ n->next->prev = n;
+ }
+ for (int i = idx; i < new_len; i++) {
+ struct addr_node *n = &new[idx++];
+ n->is_used = false;
+ }
+}
+
static struct addr_node *get_node(void) {
size_t count = BSS_NODES + alloc_node_count;
@@ -43,10 +69,13 @@ static struct addr_node *get_node(void) {
int new_alloc = alloc_node_count * 2;
if (new_alloc < 8)
new_alloc = 8;
- int allocated = new_alloc - alloc_node_count;
- int old = new_alloc - allocated;
- alloc_nodes = krealloc(alloc_nodes, sizeof(struct addr_node) * new_alloc);
- memset(alloc_nodes + old, 0, sizeof(struct addr_node) + allocated);;
+ struct addr_node *new_nodes;
+ new_nodes = kalloc(sizeof(struct addr_node) * new_alloc);
+ if (new_nodes == NULL)
+ panic("virt addr alloc nodes is null");
+ update_node_ptrs(alloc_nodes, new_nodes, alloc_node_count, new_alloc);
+ kfree(alloc_nodes);
+ alloc_nodes = new_nodes;
alloc_node_count = new_alloc;
is_allocating = false;
count = BSS_NODES + alloc_node_count;
@@ -83,26 +112,60 @@ void virtaddr_init(void) {
start_node = &bootstrap_nodes[0];
}
-void *virtaddr_alloc(int n_pages) {
+static void merge_back(struct addr_node *node) {
+ while(node->prev) {
+ if (node->is_alloc != node->prev->is_alloc)
+ break;
+ struct addr_node *temp = node->prev;
+ node->start = temp->start;
+ node->prev = temp->prev;
+ if (temp->prev)
+ temp->prev->next = node;
+ free_node(temp);
+ }
+ if (node->prev == NULL) {
+ start_node = node;
+ }
+}
+
+static void merge_forward(struct addr_node *node) {
+<<<<<<< HEAD
+ while (node->next && !node->is_alloc) {
+=======
+ while(node->next) {
+ if (node->is_alloc != node->next->is_alloc)
+ break;
+>>>>>>> ea2de5a (looping kalloc can allocate all of memory (sometimes) :3)
+ struct addr_node *temp = node->next;
+ node->end = temp->end;
+ node->next = temp->next;
+ if (temp->next)
+ temp->next->prev = node;
+ free_node(temp);
+ }
+}
+
+void *virtaddr_alloc(int n_pages) {
if (n_pages < 1)
return NULL;
-
long n_length = n_pages * PAGE_SIZE;
struct addr_node *node = start_node;
for (; node != NULL ; node = node->next) {
-
+ long length = node->end - node->start;
if (node->is_alloc)
continue;
- long length = node->end - node->start;
if (length >= n_length) {
struct addr_node *new = get_node();
if (node->prev != NULL) {
node->prev->next = new;
+ } else {
+ start_node = new;
}
new->next = node;
+ new->prev = node->prev;
node->prev = new;
new->start = node->start;
new->end = new->start + n_length;
@@ -110,34 +173,17 @@ void *virtaddr_alloc(int n_pages) {
new->is_alloc = true;
new->is_used = true;
new->next = node;
- return (void *) new->start;
+ return (void*)new->start;
+ //void *mem = (void *) new->start;
+ //merge_back(new);
+ //merge_forward(new);
+ //return mem;
}
}
return NULL;
}
-static void merge_back(struct addr_node *node) {
- while (node->prev && !node->is_alloc) {
- struct addr_node *temp = node->prev;
- node->start = node->prev->start;
- node->prev = node->prev->prev;
- free_node(temp);
- }
- if (node->prev == NULL) {
- start_node = node;
- }
-}
-
-static void merge_forward(struct addr_node *node) {
- while (node->next && !node->is_alloc) {
- struct addr_node *temp = node->next;
- node->end = node->next->end;
- node->next = node->next->next;
- free_node(temp);
- }
-}
-
long virtaddr_free(void *virtaddr) {
uintptr_t virt = (uintptr_t) virtaddr;