Properly implement liballoc_free ()
This commit is contained in:
@@ -12,5 +12,7 @@
|
|||||||
#define SYS_PROC_MUTEX_UNLOCK 9
|
#define SYS_PROC_MUTEX_UNLOCK 9
|
||||||
#define SYS_PROC_SPAWN_THREAD 10
|
#define SYS_PROC_SPAWN_THREAD 10
|
||||||
#define SYS_PROC_SCHED 11
|
#define SYS_PROC_SCHED 11
|
||||||
|
#define SYS_PROC_TRANSLATE_V2P 12
|
||||||
|
#define SYS_PROC_MEM_UNREF 13
|
||||||
|
|
||||||
#endif // _M_SYSCALL_DEFS_H
|
#endif // _M_SYSCALL_DEFS_H
|
||||||
|
|||||||
17
kernel/proc/mem.c
Normal file
17
kernel/proc/mem.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include <libk/std.h>
|
||||||
|
#include <proc/mem.h>
|
||||||
|
#include <proc/proc.h>
|
||||||
|
#include <proc/resource.h>
|
||||||
|
#include <sync/spin_lock.h>
|
||||||
|
|
||||||
|
void proc_mem_unref (struct proc* proc, struct proc_resource_mem* mem, size_t pages) {
|
||||||
|
spin_lock_ctx_t ctxrs;
|
||||||
|
|
||||||
|
spin_lock (&mem->resource->lock, &ctxrs);
|
||||||
|
mem->alive_pages -= pages;
|
||||||
|
ptrdiff_t current_pages = mem->alive_pages;
|
||||||
|
spin_unlock (&mem->resource->lock, &ctxrs);
|
||||||
|
|
||||||
|
if (current_pages <= 0)
|
||||||
|
proc_drop_resource (proc, mem->resource);
|
||||||
|
}
|
||||||
23
kernel/proc/mem.h
Normal file
23
kernel/proc/mem.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _KERNEL_PROC_MEM_H
|
||||||
|
#define _KERNEL_PROC_MEM_H
|
||||||
|
|
||||||
|
#include <libk/std.h>
|
||||||
|
|
||||||
|
struct proc;
|
||||||
|
struct proc_resource;
|
||||||
|
|
||||||
|
struct proc_resource_mem {
|
||||||
|
struct proc_resource* resource;
|
||||||
|
|
||||||
|
uintptr_t paddr;
|
||||||
|
size_t pages;
|
||||||
|
ptrdiff_t alive_pages;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct proc_resource_mem_init {
|
||||||
|
size_t pages;
|
||||||
|
};
|
||||||
|
|
||||||
|
void proc_mem_unref (struct proc* proc, struct proc_resource_mem* mem, size_t pages);
|
||||||
|
|
||||||
|
#endif // _KERNEL_PROC_MEM_H
|
||||||
@@ -10,16 +10,16 @@ void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex) {
|
|||||||
spin_lock_ctx_t ctxmt;
|
spin_lock_ctx_t ctxmt;
|
||||||
|
|
||||||
try:
|
try:
|
||||||
spin_lock (&mutex->lock, &ctxmt);
|
spin_lock (&mutex->resource->lock, &ctxmt);
|
||||||
|
|
||||||
if (!mutex->locked || mutex->owner == proc) {
|
if (!mutex->locked || mutex->owner == proc) {
|
||||||
mutex->locked = true;
|
mutex->locked = true;
|
||||||
mutex->owner = proc;
|
mutex->owner = proc;
|
||||||
spin_unlock (&mutex->lock, &ctxmt);
|
spin_unlock (&mutex->resource->lock, &ctxmt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock (&mutex->lock, &ctxmt);
|
spin_unlock (&mutex->resource->lock, &ctxmt);
|
||||||
|
|
||||||
proc_suspend (proc, &mutex->suspension_q);
|
proc_suspend (proc, &mutex->suspension_q);
|
||||||
|
|
||||||
@@ -29,10 +29,10 @@ try:
|
|||||||
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) {
|
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) {
|
||||||
spin_lock_ctx_t ctxmt, ctxsq;
|
spin_lock_ctx_t ctxmt, ctxsq;
|
||||||
|
|
||||||
spin_lock (&mutex->lock, &ctxmt);
|
spin_lock (&mutex->resource->lock, &ctxmt);
|
||||||
|
|
||||||
if (mutex->owner != proc) {
|
if (mutex->owner != proc) {
|
||||||
spin_unlock (&mutex->lock, &ctxmt);
|
spin_unlock (&mutex->resource->lock, &ctxmt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) {
|
|||||||
mutex->owner = resumed_proc;
|
mutex->owner = resumed_proc;
|
||||||
|
|
||||||
spin_unlock (&mutex->suspension_q.lock, &ctxsq);
|
spin_unlock (&mutex->suspension_q.lock, &ctxsq);
|
||||||
spin_unlock (&mutex->lock, &ctxmt);
|
spin_unlock (&mutex->resource->lock, &ctxmt);
|
||||||
proc_resume (resumed_proc);
|
proc_resume (resumed_proc);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -58,7 +58,7 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) {
|
|||||||
mutex->locked = false;
|
mutex->locked = false;
|
||||||
mutex->owner = NULL;
|
mutex->owner = NULL;
|
||||||
|
|
||||||
spin_unlock (&mutex->lock, &ctxmt);
|
spin_unlock (&mutex->resource->lock, &ctxmt);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <proc/suspension_q.h>
|
#include <proc/suspension_q.h>
|
||||||
#include <sync/spin_lock.h>
|
|
||||||
|
|
||||||
struct proc;
|
struct proc;
|
||||||
|
struct proc_resource;
|
||||||
|
|
||||||
struct proc_mutex {
|
struct proc_mutex {
|
||||||
spin_lock_t lock;
|
struct proc_resource* resource;
|
||||||
|
|
||||||
bool locked;
|
bool locked;
|
||||||
struct proc_suspension_q suspension_q;
|
struct proc_suspension_q suspension_q;
|
||||||
struct proc* owner;
|
struct proc* owner;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ static bool proc_create_resource_mem (struct proc_resource_mem* mem,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
mem->paddr = paddr;
|
mem->paddr = paddr;
|
||||||
mem->pages = init->pages;
|
mem->pages = mem->alive_pages = init->pages;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -101,12 +101,14 @@ struct proc_resource* proc_create_resource (struct proc* proc, int rid, int type
|
|||||||
struct proc_resource_mem_init* mem_init = data;
|
struct proc_resource_mem_init* mem_init = data;
|
||||||
proc_create_resource_mem (&resource->u.mem, mem_init);
|
proc_create_resource_mem (&resource->u.mem, mem_init);
|
||||||
resource->ops.cleanup = &proc_cleanup_resource_mem;
|
resource->ops.cleanup = &proc_cleanup_resource_mem;
|
||||||
|
resource->u.mem.resource = resource;
|
||||||
DEBUG ("PR_MEM resource=%p type=%d rid=%d paddr=%p, pages=%zu\n", resource, resource->type,
|
DEBUG ("PR_MEM resource=%p type=%d rid=%d paddr=%p, pages=%zu\n", resource, resource->type,
|
||||||
resource->rid, resource->u.mem.paddr, resource->u.mem.pages);
|
resource->rid, resource->u.mem.paddr, resource->u.mem.pages);
|
||||||
} break;
|
} break;
|
||||||
case PR_MUTEX: {
|
case PR_MUTEX: {
|
||||||
proc_create_resource_mutex (&resource->u.mutex);
|
proc_create_resource_mutex (&resource->u.mutex);
|
||||||
resource->ops.cleanup = &proc_cleanup_resource_mutex;
|
resource->ops.cleanup = &proc_cleanup_resource_mutex;
|
||||||
|
resource->u.mutex.resource = resource;
|
||||||
DEBUG ("PR_MUTEX resource=%p, type=%d rid=%d\n", resource, resource->type, resource->rid);
|
DEBUG ("PR_MUTEX resource=%p, type=%d rid=%d\n", resource, resource->type, resource->rid);
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <libk/rbtree.h>
|
#include <libk/rbtree.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
#include <proc/mem.h>
|
||||||
#include <proc/mutex.h>
|
#include <proc/mutex.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
|
||||||
@@ -13,15 +14,7 @@
|
|||||||
#define RV_PUBLIC 1
|
#define RV_PUBLIC 1
|
||||||
|
|
||||||
struct proc;
|
struct proc;
|
||||||
|
struct proc_resource;
|
||||||
struct proc_resource_mem {
|
|
||||||
uintptr_t paddr;
|
|
||||||
size_t pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct proc_resource_mem_init {
|
|
||||||
size_t pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct proc_resource {
|
struct proc_resource {
|
||||||
int type;
|
int type;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
c += proc/proc.c \
|
c += proc/proc.c \
|
||||||
proc/resource.c \
|
proc/resource.c \
|
||||||
proc/mutex.c
|
proc/mutex.c \
|
||||||
|
proc/mem.c
|
||||||
|
|
||||||
o += proc/proc.o \
|
o += proc/proc.o \
|
||||||
proc/resource.o \
|
proc/resource.o \
|
||||||
proc/mutex.o
|
proc/mutex.o \
|
||||||
|
proc/mem.o
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <m/status.h>
|
#include <m/status.h>
|
||||||
#include <m/syscall_defs.h>
|
#include <m/syscall_defs.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
|
#include <proc/mem.h>
|
||||||
#include <proc/mutex.h>
|
#include <proc/mutex.h>
|
||||||
#include <proc/proc.h>
|
#include <proc/proc.h>
|
||||||
#include <proc/resource.h>
|
#include <proc/resource.h>
|
||||||
@@ -130,6 +131,7 @@ DEFINE_SYSCALL (sys_proc_mutex_lock) {
|
|||||||
return ST_OK;
|
return ST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* int proc_mutex_unlock (int mutex_rid) */
|
||||||
DEFINE_SYSCALL (sys_proc_mutex_unlock) {
|
DEFINE_SYSCALL (sys_proc_mutex_unlock) {
|
||||||
spin_lock_ctx_t ctxpr;
|
spin_lock_ctx_t ctxpr;
|
||||||
int rid = (int)a1;
|
int rid = (int)a1;
|
||||||
@@ -200,6 +202,58 @@ DEFINE_SYSCALL (sys_proc_sched) {
|
|||||||
return ST_OK;
|
return ST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_SYSCALL (sys_proc_translate_v2p) {
|
||||||
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
spin_lock_ctx_t ctxprpd;
|
||||||
|
int result = ST_OK;
|
||||||
|
|
||||||
|
uintptr_t vaddr = a1;
|
||||||
|
uintptr_t* out_paddr_buf = (uintptr_t*)a2;
|
||||||
|
|
||||||
|
spin_lock (&proc->pd->lock, &ctxprpd);
|
||||||
|
|
||||||
|
uintptr_t out_paddr_buf_paddr = mm_v2p (proc->pd, (uintptr_t)out_paddr_buf, 0);
|
||||||
|
|
||||||
|
if (!mm_validate_buffer (proc->pd, (uintptr_t)out_paddr_buf, sizeof (uintptr_t), 0)) {
|
||||||
|
spin_unlock (&proc->pd->lock, &ctxprpd);
|
||||||
|
return -ST_BAD_ADDRESS_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t* out_paddr_buf_vaddr = (uintptr_t*)((uintptr_t)hhdm->offset + out_paddr_buf_paddr);
|
||||||
|
|
||||||
|
uintptr_t translated_addr = mm_v2p (proc->pd, vaddr, 0);
|
||||||
|
if (translated_addr == 0) {
|
||||||
|
result = -ST_BAD_ADDRESS_SPACE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_paddr_buf_vaddr = translated_addr;
|
||||||
|
|
||||||
|
done:
|
||||||
|
spin_unlock (&proc->pd->lock, &ctxprpd);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int proc_resource_mem_unref (int mem_rid, size_t pages) */
|
||||||
|
DEFINE_SYSCALL (sys_proc_mem_unref) {
|
||||||
|
spin_lock_ctx_t ctxpr;
|
||||||
|
int rid = (int)a1;
|
||||||
|
size_t pages = (size_t)a2;
|
||||||
|
|
||||||
|
struct proc_resource* resource;
|
||||||
|
spin_lock (&proc->lock, &ctxpr);
|
||||||
|
rbtree_find (struct proc_resource, &proc->resource_tree, rid, resource, proc_resource_tree_link,
|
||||||
|
rid);
|
||||||
|
spin_unlock (&proc->lock, &ctxpr);
|
||||||
|
|
||||||
|
if (resource == NULL)
|
||||||
|
return -ST_NOT_FOUND;
|
||||||
|
|
||||||
|
proc_mem_unref (proc, &resource->u.mem, pages);
|
||||||
|
|
||||||
|
return ST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static syscall_handler_func_t handler_table[] = {
|
static syscall_handler_func_t handler_table[] = {
|
||||||
[SYS_PROC_QUIT] = &sys_proc_quit,
|
[SYS_PROC_QUIT] = &sys_proc_quit,
|
||||||
[SYS_PROC_TEST] = &sys_proc_test,
|
[SYS_PROC_TEST] = &sys_proc_test,
|
||||||
@@ -212,6 +266,8 @@ static syscall_handler_func_t handler_table[] = {
|
|||||||
[SYS_PROC_MUTEX_UNLOCK] = &sys_proc_mutex_unlock,
|
[SYS_PROC_MUTEX_UNLOCK] = &sys_proc_mutex_unlock,
|
||||||
[SYS_PROC_SPAWN_THREAD] = &sys_proc_spawn_thread,
|
[SYS_PROC_SPAWN_THREAD] = &sys_proc_spawn_thread,
|
||||||
[SYS_PROC_SCHED] = &sys_proc_sched,
|
[SYS_PROC_SCHED] = &sys_proc_sched,
|
||||||
|
[SYS_PROC_TRANSLATE_V2P] = &sys_proc_translate_v2p,
|
||||||
|
[SYS_PROC_MEM_UNREF] = &sys_proc_mem_unref,
|
||||||
};
|
};
|
||||||
|
|
||||||
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
static int liballoc_mutex;
|
static int liballoc_mutex;
|
||||||
static uintptr_t liballoc_map_base = PROC_MAP_BASE;
|
static uintptr_t liballoc_map_base = PROC_MAP_BASE;
|
||||||
static int mem_rid_base = 10000;
|
static int mem_rid_base = 1000000;
|
||||||
|
|
||||||
void liballoc_init (void) { liballoc_mutex = proc_create_resource_mutex (100, RV_PRIVATE); }
|
void liballoc_init (void) { liballoc_mutex = proc_create_resource_mutex (100, RV_PRIVATE); }
|
||||||
|
|
||||||
@@ -36,7 +36,20 @@ void* liballoc_alloc (int pages) {
|
|||||||
return (void*)old_base;
|
return (void*)old_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
int liballoc_free (void* ptr, int pages) { return 0; }
|
int liballoc_free (void* ptr, int pages) {
|
||||||
|
int res;
|
||||||
|
uintptr_t out_paddr;
|
||||||
|
|
||||||
|
res = proc_translate_v2p ((uintptr_t)ptr, &out_paddr);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = proc_unmap ((uintptr_t)ptr, pages);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return proc_mem_unref (out_paddr, pages);
|
||||||
|
}
|
||||||
|
|
||||||
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
|
/** Durand's Ridiculously Amazing Super Duper Memory functions. */
|
||||||
|
|
||||||
|
|||||||
@@ -41,4 +41,12 @@ int proc_spawn_thread (uintptr_t vstack_top, size_t stack_size, void* entry) {
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int proc_translate_v2p (uintptr_t vaddr, uintptr_t* out_paddr) {
|
||||||
|
return syscall (SYS_PROC_TRANSLATE_V2P, vaddr, (uintptr_t)out_paddr, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int proc_mem_unref (uintptr_t paddr, size_t pages) {
|
||||||
|
return syscall (SYS_PROC_MEM_UNREF, paddr, (uintptr_t)pages, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int proc_sched (void) { return syscall (SYS_PROC_SCHED, 0, 0, 0, 0, 0, 0); }
|
int proc_sched (void) { return syscall (SYS_PROC_SCHED, 0, 0, 0, 0, 0, 0); }
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ int proc_mutex_lock (int mutex_rid);
|
|||||||
int proc_mutex_unlock (int mutex_rid);
|
int proc_mutex_unlock (int mutex_rid);
|
||||||
int proc_spawn_thread (uintptr_t vstack_top, size_t stack_size, void* entry);
|
int proc_spawn_thread (uintptr_t vstack_top, size_t stack_size, void* entry);
|
||||||
int proc_sched (void);
|
int proc_sched (void);
|
||||||
int proc_translate_resource_mem (uintptr_t vaddr);
|
int proc_translate_v2p (uintptr_t vaddr, uintptr_t* out_paddr);
|
||||||
|
int proc_mem_unref (uintptr_t paddr, size_t pages);
|
||||||
|
|
||||||
#endif // _LIBMSL_M_PROC_H
|
#endif // _LIBMSL_M_PROC_H
|
||||||
|
|||||||
Reference in New Issue
Block a user