This commit is contained in:
2026-10-25 17:07:40 +01:00
parent c1a5e9021a
commit d63724ea61
5 changed files with 233 additions and 2 deletions
+32
View File
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: ISC
#pragma once
#include <zinnia/atomic.h>
#include <zinnia/errno.h>
#include <zinnia/mutex.h>
#include <zinnia/radix.h>
#include <zinnia/refcount.h>
#include <zinnia/virt.h>
#include <stddef.h>
struct vm_anon {
_Atomic(size_t) rc;
struct page* page;
};
struct amap {
struct refcount rc;
mutex_t lock;
struct radix_tree anons;
};
errno_t anon_new(struct page* src, struct vm_anon** out);
void anon_ref(struct vm_anon* anon);
void anon_unref(struct vm_anon* anon);
errno_t amap_new(struct amap** out);
void amap_ref(struct amap* amap);
void amap_unref(struct amap* amap);
bool amap_is_shared(struct amap* amap);
errno_t amap_copy(struct amap* src, size_t offset, size_t num_slots, struct amap** out);
+24 -2
View File
@@ -2,6 +2,9 @@
#pragma once
#include <zinnia/alloc.h>
#include <zinnia/atomic.h>
#include <zinnia/errno.h>
#include <zinnia/hashmap.h>
#include <zinnia/types.h>
#include <stddef.h>
@@ -11,15 +14,26 @@ enum page_type : uint8_t {
PAGE_PHYS = 0, // Regular physical memory.
};
enum page_flags : uint32_t {
PAGE_BUSY = 1 << 0,
PAGE_WANTED = 1 << 1,
PAGE_DIRTY = 1 << 2,
PAGE_ANON = 1 << 3,
};
struct page {
enum page_type type;
uint32_t flags;
size_t refcount;
_Atomic(uint32_t) flags;
_Atomic(size_t) holds;
union {
struct {
struct page* next; // Pointer to the next chunk.
size_t count; // Amount of free pages.
} freelist;
struct {
void* owner;
uint64_t index;
} obj;
};
};
static_assert(0x1000 % sizeof(struct page) == 0, "struct must fit cleanly inside a page!");
@@ -29,6 +43,14 @@ static_assert(sizeof(struct page) <= 64, "struct must be smaller than 64 bytes!"
extern struct page* vm_pfndb;
uintptr_t vm_page_addr(struct page* page);
struct page* vm_page_from_addr(phys_t addr);
errno_t page_alloc(enum alloc_flags flags, struct page** out);
void page_hold(struct page* page);
void page_unhold(struct page* page);
bool page_try_busy(struct page* page);
void page_unbusy(struct page* page);
void page_wait(struct page* page);
// Allocator for virtual memory.
struct vm_alloc {