From 7eceecf6e3138adf86dfa9d68e633ffdcc218752 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 20 Jan 2026 22:18:43 +0100 Subject: [PATCH] Add mutex syscalls --- include/m/syscall_defs.h | 4 +++ init/init.c | 26 ++++++++------ kernel/proc/resource.c | 8 ++--- kernel/syscall/syscall.c | 78 +++++++++++++++++++++++++++++++++++++++- libmsl/alloc/liballoc.c | 10 ++++-- libmsl/alloc/liballoc.h | 1 + libmsl/init/__premain.c | 3 +- libmsl/m/system.c | 10 +++++- libmsl/m/system.h | 4 +++ 9 files changed, 122 insertions(+), 22 deletions(-) diff --git a/include/m/syscall_defs.h b/include/m/syscall_defs.h index bfdd6a2..877a199 100644 --- a/include/m/syscall_defs.h +++ b/include/m/syscall_defs.h @@ -9,5 +9,9 @@ #define SYS_SCHED 6 #define SYS_CREATE_MEM 7 #define SYS_UNLINK_MEM 8 +#define SYS_CREATE_MUTEX 9 +#define SYS_UNLINK_MUTEX 10 +#define SYS_LOCK_MUTEX 11 +#define SYS_UNLOCK_MUTEX 12 #endif // _M_SYSCALL_DEFS_H diff --git a/init/init.c b/init/init.c index 9d26abf..5f07d56 100644 --- a/init/init.c +++ b/init/init.c @@ -9,17 +9,21 @@ #define EXAMPLE 1 #if EXAMPLE == 1 -void app_main (void) { - test ('a'); - test ('a'); - test ('a'); - int* xs = malloc (1024 * sizeof (*xs)); - memset (xs, 123, 1024 * sizeof (*xs)); - free (xs); - - test ('a'); - test ('a'); - test ('a'); +void app_thread1 (void) { + test ('b'); + quit (); } + +int spawn (void (*fn) (void)) { + size_t stack_size = 256 * PAGE_SIZE; + void* stack = malloc (stack_size); + if (stack == NULL) + return -ST_OOM_ERROR; + + uintptr_t stack_top = (uintptr_t)stack + stack_size; + return clone (stack_top, stack_size, fn); +} + +void app_main (void) { spawn (&app_thread1); } #endif diff --git a/kernel/proc/resource.c b/kernel/proc/resource.c index e3a7089..8116a25 100644 --- a/kernel/proc/resource.c +++ b/kernel/proc/resource.c @@ -43,11 +43,11 @@ void proc_cleanup_resources (struct proc* proc) { void proc_drop_resource (struct proc* proc, struct proc_resource* resource, bool lock) { spin_lock_ctx_t ctxrs; - DEBUG ("resource=%p created_by=%d vis=%d type=%d rid=%d refs=%d\n", resource, - resource->created_by_pid, resource->visibility, resource->type, resource->rid, - atomic_load (&resource->refs)); - if (atomic_fetch_sub (&resource->refs, 1) == 1) { + DEBUG ("resource=%p created_by=%d vis=%d type=%d rid=%d refs=%d\n", resource, + resource->created_by_pid, resource->visibility, resource->type, resource->rid, + atomic_load (&resource->refs)); + switch (resource->visibility) { case RV_PRIVATE: { if (lock) diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 87d223d..0cb1444 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -177,12 +177,84 @@ DEFINE_SYSCALL (sys_clone) { return pid; } -/* int proc_sched (void) */ +/* int sched (void) */ DEFINE_SYSCALL (sys_sched) { proc_sched (regs); return ST_OK; } +/* int create_mutex (int mutex_rid, int vis) */ +DEFINE_SYSCALL (sys_create_mutex) { + int mutex_rid = (int)a1; + int vis = (int)a2; + + if (mutex_rid < 0) + return -ST_BAD_RESOURCE; + + if (!(vis == RV_PUBLIC || vis == RV_PRIVATE)) + return -ST_BAD_RESOURCE; + + struct proc_resource* mutex_resource = + proc_create_resource (proc, mutex_rid, PR_MUTEX, vis, NULL); + + if (mutex_resource == NULL) + return -ST_OOM_ERROR; + + return mutex_resource->rid; +} + +/* int unlink_mutex (int mutex_rid, int vis) */ +DEFINE_SYSCALL (sys_unlink_mutex) { + int mutex_rid = (int)a1; + int vis = (int)a2; + + if (!(vis == RV_PUBLIC || vis == RV_PRIVATE)) + return -ST_BAD_RESOURCE; + + struct proc_resource* mutex_resource = proc_find_resource (proc, mutex_rid, vis); + + if (mutex_resource == NULL) + return -ST_NOT_FOUND; + + proc_drop_resource (proc, mutex_resource, true); + + return ST_OK; +} + +/* int lock_mutex (int mutex_rid, int vis) */ +DEFINE_SYSCALL (sys_lock_mutex) { + int mutex_rid = (int)a1; + int vis = (int)a2; + + if (!(vis == RV_PUBLIC || vis == RV_PRIVATE)) + return -ST_BAD_RESOURCE; + + struct proc_resource* mutex_resource = proc_find_resource (proc, mutex_rid, vis); + + if (mutex_resource == NULL) + return -ST_NOT_FOUND; + + proc_mutex_lock (proc, &mutex_resource->u.mutex); + + return ST_OK; +} + +/* int unlock_mutex (int mutex_rid, int vis) */ +DEFINE_SYSCALL (sys_unlock_mutex) { + int mutex_rid = (int)a1; + int vis = (int)a2; + + if (!(vis == RV_PUBLIC || vis == RV_PRIVATE)) + return -ST_BAD_RESOURCE; + + struct proc_resource* mutex_resource = proc_find_resource (proc, mutex_rid, vis); + + if (mutex_resource == NULL) + return -ST_NOT_FOUND; + + return proc_mutex_unlock (proc, &mutex_resource->u.mutex) ? ST_OK : -ST_PERMISSION_ERROR; +} + static syscall_handler_func_t handler_table[] = { [SYS_QUIT] = &sys_quit, [SYS_TEST] = &sys_test, @@ -192,6 +264,10 @@ static syscall_handler_func_t handler_table[] = { [SYS_SCHED] = &sys_sched, [SYS_CREATE_MEM] = &sys_create_mem, [SYS_UNLINK_MEM] = &sys_unlink_mem, + [SYS_CREATE_MUTEX] = &sys_create_mutex, + [SYS_UNLINK_MUTEX] = &sys_unlink_mutex, + [SYS_LOCK_MUTEX] = &sys_lock_mutex, + [SYS_UNLOCK_MUTEX] = &sys_unlock_mutex, }; syscall_handler_func_t syscall_find_handler (int syscall_num) { diff --git a/libmsl/alloc/liballoc.c b/libmsl/alloc/liballoc.c index 5040ca9..34d0306 100644 --- a/libmsl/alloc/liballoc.c +++ b/libmsl/alloc/liballoc.c @@ -4,14 +4,18 @@ #include #include +#define LIBALLOC_MUTEX 500 + static uintptr_t liballoc_map_base = PROC_MAP_BASE; static int mem_rid_base = 1000000; -void liballoc_init (void) {} +void liballoc_init (void) { create_mutex (LIBALLOC_MUTEX, RV_PRIVATE); } -int liballoc_lock (void) { return 0; } +void liballoc_deinit (void) { unlink_mutex (LIBALLOC_MUTEX, RV_PRIVATE); } -int liballoc_unlock (void) { return 0; } +int liballoc_lock (void) { return lock_mutex (LIBALLOC_MUTEX, RV_PRIVATE); } + +int liballoc_unlock (void) { return unlock_mutex (LIBALLOC_MUTEX, RV_PRIVATE); } void* liballoc_alloc (int pages, int* mem_rid) { uintptr_t current_base = liballoc_map_base; diff --git a/libmsl/alloc/liballoc.h b/libmsl/alloc/liballoc.h index a5449c7..07c981b 100644 --- a/libmsl/alloc/liballoc.h +++ b/libmsl/alloc/liballoc.h @@ -87,6 +87,7 @@ void* calloc (size_t, size_t); //< The standard function. void free (void*); //< The standard function. void liballoc_init (void); +void liballoc_deinit (void); #ifdef __cplusplus } diff --git a/libmsl/init/__premain.c b/libmsl/init/__premain.c index 8781c8f..ccaed44 100644 --- a/libmsl/init/__premain.c +++ b/libmsl/init/__premain.c @@ -17,8 +17,7 @@ static void clear_bss (void) { void __premain (void) { clear_bss (); liballoc_init (); - app_main (); - + liballoc_deinit (); quit (); } diff --git a/libmsl/m/system.c b/libmsl/m/system.c index cfded00..d47469c 100644 --- a/libmsl/m/system.c +++ b/libmsl/m/system.c @@ -9,7 +9,7 @@ #define do_syscall(...) do_syscall1 (__VA_ARGS__, 0, 0, 0, 0, 0, 0) -int quit (void) { return do_syscall (SYS_QUIT); } +int quit (void) { return do_syscall (SYS_QUIT, 0); } int test (char c) { return do_syscall (SYS_TEST, c); } @@ -30,3 +30,11 @@ int unlink_mem (int mem_rid, int vis, size_t pages) { int clone (uintptr_t vstack_top, size_t stack_size, void (*entry) (void)) { return do_syscall (SYS_CLONE, vstack_top, stack_size, entry); } + +int create_mutex (int mutex_rid, int vis) { return do_syscall (SYS_CREATE_MUTEX, mutex_rid, vis); } + +int unlink_mutex (int mutex_rid, int vis) { return do_syscall (SYS_UNLINK_MUTEX, mutex_rid, vis); } + +int lock_mutex (int mutex_rid, int vis) { return do_syscall (SYS_LOCK_MUTEX, mutex_rid, vis); } + +int unlock_mutex (int mutex_rid, int vis) { return do_syscall (SYS_UNLOCK_MUTEX, mutex_rid, vis); } diff --git a/libmsl/m/system.h b/libmsl/m/system.h index 8355d8a..85da0b0 100644 --- a/libmsl/m/system.h +++ b/libmsl/m/system.h @@ -24,5 +24,9 @@ int unmap (uintptr_t vaddr, size_t pages); int create_mem (int mem_rid, int vis, size_t pages); int unlink_mem (int mem_rid, int vis, size_t pages); int clone (uintptr_t vstack_top, size_t stack_size, void (*entry) (void)); +int create_mutex (int mutex_rid, int vis); +int unlink_mutex (int mutex_rid, int vis); +int lock_mutex (int mutex_rid, int vis); +int unlock_mutex (int mutex_rid, int vis); #endif // _LIBMSL_M_SYSTEM_H