summaryrefslogtreecommitdiff
path: root/sys/vm/vm_physmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_physmem.c')
-rw-r--r--sys/vm/vm_physmem.c63
1 files changed, 45 insertions, 18 deletions
diff --git a/sys/vm/vm_physmem.c b/sys/vm/vm_physmem.c
index c7fcedb..89f9ee6 100644
--- a/sys/vm/vm_physmem.c
+++ b/sys/vm/vm_physmem.c
@@ -36,11 +36,12 @@
#include <vm/vm.h>
#include <string.h>
-size_t highest_frame_idx = 0;
-size_t bitmap_size = 0;
-size_t bitmap_free_start = 0;
+static size_t highest_frame_idx = 0;
+static size_t bitmap_size = 0;
+static size_t bitmap_free_start = 0;
+static ssize_t last_idx = 0;
-uint8_t *bitmap;
+static uint8_t *bitmap;
static struct limine_memmap_response *resp = NULL;
static struct spinlock lock = {0};
@@ -137,27 +138,51 @@ physmem_init_bitmap(void)
*
* @count: Number of frames to allocate.
*/
-uintptr_t
-vm_alloc_frame(size_t count)
+static uintptr_t
+__vm_alloc_frame(size_t count)
{
size_t frames = 0;
+ ssize_t idx = -1;
uintptr_t ret = 0;
- spinlock_acquire(&lock);
- for (size_t i = 0; i < highest_frame_idx; ++i) {
+ for (size_t i = last_idx; i < highest_frame_idx; ++i) {
if (!testbit(bitmap, i)) {
- /* We have a free page */
- if (++frames != count) {
- continue;
- }
+ if (idx < 0)
+ idx = i;
+ if (++frames >= count)
+ break;
- for (size_t j = i; j < i + count; ++j) {
- setbit(bitmap, j);
- }
-
- ret = i * DEFAULT_PAGESIZE;
- break;
+ continue;
}
+
+ idx = -1;
+ frames = 0;
+ }
+
+ if (idx < 0 || frames != count) {
+ ret = 0;
+ goto done;
+ }
+
+ for (size_t i = idx; i < idx + count; ++i) {
+ setbit(bitmap, i);
+ }
+ ret = idx * DEFAULT_PAGESIZE;
+ last_idx = idx;
+ memset(PHYS_TO_VIRT(ret), 0, count * DEFAULT_PAGESIZE);
+done:
+ return ret;
+}
+
+uintptr_t
+vm_alloc_frame(size_t count)
+{
+ uintptr_t ret;
+
+ spinlock_acquire(&lock);
+ if ((ret = __vm_alloc_frame(count)) == 0) {
+ last_idx = 0;
+ ret = __vm_alloc_frame(count);
}
spinlock_release(&lock);
@@ -169,6 +194,8 @@ vm_free_frame(uintptr_t base, size_t count)
{
size_t stop_at = base + (count * DEFAULT_PAGESIZE);
+ base = ALIGN_UP(base, DEFAULT_PAGESIZE);
+
spinlock_acquire(&lock);
for (uintptr_t p = base; p < stop_at; p += DEFAULT_PAGESIZE) {
clrbit(bitmap, p / DEFAULT_PAGESIZE);