summaryrefslogtreecommitdiff
path: root/src/memory
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory')
-rw-r--r--src/memory/memory.c34
-rw-r--r--src/memory/physalloc.c25
-rw-r--r--src/memory/virtalloc.c81
3 files changed, 86 insertions, 54 deletions
diff --git a/src/memory/memory.c b/src/memory/memory.c
index 1c69bae..af63865 100644
--- a/src/memory/memory.c
+++ b/src/memory/memory.c
@@ -1,10 +1,8 @@
+#include "serial.h"
#include <memory.h>
#include <stdint.h>
#include <lib.h>
-
-#ifdef MEMORY_PANIC
#include <panic.h>
-#endif
#define MAGIC 0xBEEFCAFE
@@ -18,8 +16,8 @@ struct page_header {
};
static const size_t header_len = sizeof(struct page_header);
-struct page_header *start_header = NULL;
-struct page_header *end_header = NULL;
+static struct page_header *start_header = NULL;
+static struct page_header *end_header = NULL;
struct page_header* get_header(void *ptr) {
struct page_header *header =
@@ -36,6 +34,7 @@ struct page_header* get_header(void *ptr) {
void *kalloc_new(size_t size) {
size_t pages = ((size + header_len) / PAGE_SIZE) + 1;
+
void *addr = alloc_pages(pages);
void *mem = (char *)addr + header_len;
@@ -54,20 +53,20 @@ void *kalloc_new(size_t size) {
}
struct page_header *header = addr;
- header->magic = MAGIC;
+ header->magic = 0xBEEFCAFE;
header->used = size;
header->free = free;
header->prev = end_header;
header->next = NULL;
header->node_number = node;
- if (end_header == NULL) {
+ if (start_header == NULL) {
start_header = header;
- } else {
- end_header->next = header;
}
- end_header = header;
+ if (end_header != NULL) {
+ end_header->next = header;
+ }
return mem;
}
@@ -97,6 +96,9 @@ void *kalloc(size_t size) {
for (; header != NULL; header = header->next) {
size_t free = header->free;
+ if (free < header_len) {
+ continue;
+ }
if (size <= (free - header_len)) { // we must be able to fit data + header
break;
}
@@ -129,21 +131,13 @@ void *krealloc(void *src, size_t dst_len) {
header = get_header(src);
if (header == NULL) {
-#ifdef MEMORY_PANIC
panic("attempted to realloc on a invalid ptr");
-#else
- return NULL; // invalid pointer passed
-#endif
}
src_len = header->used;
if (src_len == 0) {
-#ifdef MEMORY_PANIC
panic("attempted to realloc on an empty ptr");
-#else
- return NULL; // likely double free :(
-#endif
}
dst = kalloc(dst_len);
@@ -166,11 +160,7 @@ void kfree(void *ptr) {
header = get_header(ptr);
if (header == NULL || header->used == 0) {
-#ifdef MEMORY_PANIC
panic("attempted to kfree invalid pointer");
-#else
- return;
-#endif
}
header->free += header->used;
diff --git a/src/memory/physalloc.c b/src/memory/physalloc.c
index 1140258..bcbc66d 100644
--- a/src/memory/physalloc.c
+++ b/src/memory/physalloc.c
@@ -1,3 +1,4 @@
+#include "serial.h"
#include <memory.h>
#include <stdint.h>
#include <lib.h>
@@ -63,6 +64,10 @@ static inline bool bitmap_get(int i) {
}
static inline void bitmap_set(int i, bool v) {
+ if (v)
+ free_memory -= PAGE_SIZE;
+ else
+ free_memory += PAGE_SIZE;
int idx = i / 64;
bitmap[idx] &= ~(1 << i % 64);
bitmap[idx] |= (v << i % 64);
@@ -115,11 +120,11 @@ void free_phys_pages(void *ptr, int pages) {
}
static bool segment_invalid(const struct memory_segment *segment) {
- if (segment->type != 1) return false;
- if (segment->addr < kaddr(kernel_start)) return false;
- if (segment->addr + segment->len < memory_start) return false;
- if (segment->addr + segment->len < kaddr(kernel_start)) return false;
- return true;
+ if (segment->type != 1) return true;
+ if (segment->addr < kaddr(kernel_start)) return true;
+ if (segment->addr + segment->len < memory_start) return true;
+ if (segment->addr + segment->len < kaddr(kernel_start)) return true;
+ return false;
}
static struct memory_area segment_to_area(const struct memory_segment *segment) {
@@ -195,18 +200,28 @@ void memory_init(struct memory_map *map) {
struct memory_area *area = page_start;
+ kprintf("MEMORY MAP\n");
for(uint32_t i = 0; i < map->entry_count; i++) {
struct memory_segment *segment = &map->entries[i];
if (segment_invalid(segment))
continue;
+ kprintf("addr: 0x%16p\tlen: %ld\n", (void *)segment->addr, segment->len);
+
struct memory_area temp = segment_to_area(segment);
*area = temp;
area++;
}
+ total_memory = page_count * PAGE_SIZE;
page_count -= bitmap_pages;
+ free_memory = page_count * PAGE_SIZE;
+
+ kprintf("\nMEMORY USAGE\n");
+ kprintf("mem total: %ld\n", memory_total());
+ kprintf("mem free: %ld\n", memory_free());
+ kprintf("mem used: %ld\n\n", memory_used());
memory_unlock();
diff --git a/src/memory/virtalloc.c b/src/memory/virtalloc.c
index 781fc9b..2ab9fc2 100644
--- a/src/memory/virtalloc.c
+++ b/src/memory/virtalloc.c
@@ -1,6 +1,9 @@
+#include "lib.h"
+#include "panic.h"
#include <stdint.h>
#include <stddef.h>
#include <memory.h>
+#include <string.h>
#define MEMORY_INTERNAL
#include <memory/virtalloc.h>
@@ -10,34 +13,60 @@ struct addr_node {
uintptr_t end;
struct addr_node *next;
struct addr_node *prev;
- uint8_t is_alloc;
- uint8_t is_bss;
+ uint8_t is_alloc; // if node is storing allocated data
+ uint8_t is_used; // if node is in use by virtalloc
};
-#define BOOTSTRAP_BSS_NODES 16
-static uint8_t bss_nodes = 0;
-static struct addr_node nodes[BOOTSTRAP_BSS_NODES];
+#define BSS_NODES 64
+static struct addr_node bootstrap_nodes[BSS_NODES];
+static struct addr_node *alloc_nodes = NULL;
+static size_t free_node_start = 0;
+static size_t alloc_node_count = 0;
+static size_t used_node_count = 0;
+static bool is_allocating = false;
-static struct addr_node *start_node;
+static struct addr_node *start_node = NULL;
-static struct addr_node *alloc_node(void) {
- struct addr_node *node = NULL;
- if (bss_nodes >= BOOTSTRAP_BSS_NODES) {
- node = kalloc(sizeof(struct addr_node));
- if (node == NULL)
- return NULL;
- node->is_bss = false;
+static struct addr_node *get_node_idx(int idx) {
+ if (idx < BSS_NODES) {
+ return &bootstrap_nodes[idx];
} else {
- node = &nodes[bss_nodes];
- bss_nodes += 1;
- node->is_bss = true;
+ return &alloc_nodes[idx - BSS_NODES];
}
- return node;
+}
+
+static struct addr_node *get_node(void) {
+ size_t count = BSS_NODES + alloc_node_count;
+
+ if (!is_allocating && used_node_count + 16 >= count) {
+ is_allocating = true;
+ 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);;
+ alloc_node_count = new_alloc;
+ is_allocating = false;
+ count = BSS_NODES + alloc_node_count;
+ }
+
+ size_t idx = free_node_start;
+ for (; idx < count; idx++) {
+ struct addr_node *node = get_node_idx(idx);
+ if (!node->is_used) {
+ used_node_count++;
+ return node;
+ }
+ }
+
+ panic("could not get virtaddr node");
}
static void free_node(struct addr_node *node) {
- if (!node->is_bss)
- kfree(node);
+ node->is_used = false;
+ used_node_count--;
}
void virtaddr_init(void) {
@@ -47,11 +76,11 @@ void virtaddr_init(void) {
.next = NULL,
.prev = NULL,
.is_alloc = false,
- .is_bss = true,
+ .is_used = true,
};
- nodes[0] = init;
- start_node = &nodes[0];
- bss_nodes++;
+ memset(bootstrap_nodes, 0, sizeof(bootstrap_nodes));
+ bootstrap_nodes[0] = init;
+ start_node = &bootstrap_nodes[0];
}
void *virtaddr_alloc(int n_pages) {
@@ -69,10 +98,7 @@ void *virtaddr_alloc(int n_pages) {
long length = node->end - node->start;
if (length >= n_length) {
- struct addr_node *new = alloc_node();
- if (node == NULL) {
- return NULL;
- }
+ struct addr_node *new = get_node();
if (node->prev != NULL) {
node->prev->next = new;
}
@@ -82,6 +108,7 @@ void *virtaddr_alloc(int n_pages) {
new->end = new->start + n_length;
node->start = new->end;
new->is_alloc = true;
+ new->is_used = true;
new->next = node;
return (void *) new->start;
}