From 084809ac9932c10441c421f4ecccfb5b78972223 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sun, 22 Feb 2026 20:40:12 +0100 Subject: [PATCH] Manage int IDs via id_alloc --- kernel/amd64/bootmain.c | 3 + kernel/amd64/proc.c | 17 +++-- kernel/fs/vfs.c | 17 +++-- kernel/fs/vfs.h | 1 - kernel/id/.gitignore | 1 + kernel/id/id_alloc.c | 52 ++++++++++++++++ kernel/id/id_alloc.h | 21 +++++++ kernel/id/src.mk | 3 + kernel/make/src.mk | 1 + kernel/proc/proc.c | 11 ++++ kernel/proc/proc.h | 6 ++ kernel/proc/procgroup.c | 133 +++++++++++++++++++++++----------------- kernel/proc/procgroup.h | 7 ++- 13 files changed, 203 insertions(+), 70 deletions(-) create mode 100644 kernel/id/.gitignore create mode 100644 kernel/id/id_alloc.c create mode 100644 kernel/id/id_alloc.h create mode 100644 kernel/id/src.mk diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index 0be6e32..3ca96e6 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -64,6 +64,9 @@ void bootmain (void) { spin (); } + proc_pid_alloc_init (); + procgroup_pgid_alloc_init (); + smp_init (); proc_init (); diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index 11913a4..0587073 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -17,8 +17,6 @@ #include #include -static atomic_int pids = 0; - struct proc* proc_from_elf (uint8_t* elf_contents) { struct limine_hhdm_response* hhdm = limine_hhdm_request.response; @@ -30,7 +28,12 @@ struct proc* proc_from_elf (uint8_t* elf_contents) { proc->lock = SPIN_LOCK_INIT; proc->state = PROC_READY; - proc->pid = atomic_fetch_add (&pids, 1); + proc->pid = proc_alloc_pid (); + + if (proc->pid < 0) { + free (proc); + return NULL; + } proc->procgroup = procgroup_create (); if (proc->procgroup == NULL) { @@ -72,7 +75,12 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent proc->lock = SPIN_LOCK_INIT; proc->state = PROC_READY; - proc->pid = atomic_fetch_add (&pids, 1); + proc->pid = proc_alloc_pid (); + + if (proc->pid < 0) { + free (proc); + return NULL; + } spin_lock (&proto->lock); @@ -108,6 +116,7 @@ void proc_cleanup (struct proc* proc, struct reschedule_ctx* rctx) { procgroup_detach (proc->procgroup, proc, rctx); + proc_free_pid (proc->pid); /* clean the process */ free (proc); } diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index a950f9f..f1f4949 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -97,7 +98,7 @@ int vfs_open (struct procgroup* procgroup, const char* mountpoint, const char* p spin_lock (&procgroup->lock); - int id = handle->id = procgroup->sys_vfs_handles++; + int id = handle->id = id_alloc (&procgroup->vfs_handle_id_alloc); rbtree_insert (struct vfs_handle, &procgroup->vfs_handle_tree, &handle->handle_tree_link, handle_tree_link, id); @@ -119,8 +120,13 @@ int vfs_close (struct procgroup* procgroup, int id) { return -ST_NOT_FOUND; } + spin_lock (&handle->lock); + rbtree_delete (&procgroup->vfs_handle_tree, &handle->handle_tree_link); + id_free (&procgroup->vfs_handle_id_alloc, handle->id); + + spin_unlock (&handle->lock); spin_unlock (&procgroup->lock); free (handle); @@ -191,7 +197,6 @@ int vfs_kernel_describe (const char* mountpoint, const char* path, struct desc* } void vfs_procgroup_cleanup (struct procgroup* procgroup) { - struct list_node_link* handle_cleanup_list = NULL; struct vfs_handle* handle; struct rb_node_link* node; @@ -202,14 +207,8 @@ void vfs_procgroup_cleanup (struct procgroup* procgroup) { rbtree_next (node, next); handle = rbtree_entry (node, struct vfs_handle, handle_tree_link); node = next; - list_append (handle_cleanup_list, &handle->handle_cleanup_link); - } - struct list_node_link *cleanup_link, *cleanup_tmp_link; - list_foreach (handle_cleanup_list, cleanup_link, cleanup_tmp_link) { - handle = list_entry (cleanup_link, struct vfs_handle, handle_cleanup_link); - list_remove (handle_cleanup_list, &handle->handle_cleanup_link); - free (handle); + vfs_close (procgroup, handle->id); } } diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 86a8a29..cf3c33b 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -23,7 +23,6 @@ struct vfs_handle { char path[MAX_PATH]; struct procgroup* ownerpg; struct rb_node_link handle_tree_link; - struct list_node_link handle_cleanup_link; spin_lock_t lock; }; diff --git a/kernel/id/.gitignore b/kernel/id/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/kernel/id/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/kernel/id/id_alloc.c b/kernel/id/id_alloc.c new file mode 100644 index 0000000..ee6a2ad --- /dev/null +++ b/kernel/id/id_alloc.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include + +bool id_alloc_init (struct id_alloc* ida, size_t nbits) { + size_t buffer_size = (nbits + 7) / 8; + + uint8_t* buffer = malloc (buffer_size); + + if (buffer == NULL) + return false; + + bm_init (&ida->bm, buffer, nbits); + ida->lock = SPIN_LOCK_INIT; + + return true; +} + +void id_alloc_fini (struct id_alloc* ida) { + free (ida->bm.base); + ida->bm.base = NULL; + ida->bm.nbits = 0; +} + +int id_alloc (struct id_alloc* ida) { + spin_lock (&ida->lock); + + for (size_t bit = 0; bit < ida->bm.nbits; bit++) { + if (!bm_test (&ida->bm, bit)) { + bm_set (&ida->bm, bit); + + spin_unlock (&ida->lock); + return (int)bit; + } + } + + spin_unlock (&ida->lock); + return -ST_OOM_ERROR; +} + +void id_free (struct id_alloc* ida, int id) { + if (id < 0) + return; + + spin_lock (&ida->lock); + bm_clear (&ida->bm, (size_t)id); + spin_unlock (&ida->lock); +} diff --git a/kernel/id/id_alloc.h b/kernel/id/id_alloc.h new file mode 100644 index 0000000..4356815 --- /dev/null +++ b/kernel/id/id_alloc.h @@ -0,0 +1,21 @@ +#ifndef _KERNEL_ID_ID_ALLOC_H +#define _KERNEL_ID_ID_ALLOC_H + +#include +#include +#include + +struct id_alloc { + struct bm bm; + spin_lock_t lock; +}; + +int id_alloc (struct id_alloc* ida); + +void id_free (struct id_alloc* ida, int id); + +bool id_alloc_init (struct id_alloc* ida, size_t nbits); + +void id_alloc_fini (struct id_alloc* ida); + +#endif // _KERNEL_ID_ID_ALLOC_H diff --git a/kernel/id/src.mk b/kernel/id/src.mk new file mode 100644 index 0000000..6a75793 --- /dev/null +++ b/kernel/id/src.mk @@ -0,0 +1,3 @@ +c += id/id_alloc.c + +o += id/id_alloc.o diff --git a/kernel/make/src.mk b/kernel/make/src.mk index 9aa0ed8..7924ef2 100644 --- a/kernel/make/src.mk +++ b/kernel/make/src.mk @@ -9,6 +9,7 @@ include syscall/src.mk include fs/src.mk include device/src.mk include Flanterm/src.mk +include id/src.mk ifeq ($(PLATFORM_ACPI),1) include uACPI/src.mk diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 14315f6..3bde259 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,8 @@ #include #endif +#define PIDS_MAX 1024 + #define SCHED_REAP_FREQ 10 static struct rb_node_link* proc_tree = NULL; @@ -36,6 +39,14 @@ static spin_lock_t proc_tree_lock = SPIN_LOCK_INIT; static atomic_int sched_cycles = 0; +static struct id_alloc pid_alloc; + +int proc_alloc_pid (void) { return id_alloc (&pid_alloc); } + +void proc_free_pid (int pid) { id_free (&pid_alloc, pid); } + +void proc_pid_alloc_init (void) { id_alloc_init (&pid_alloc, PIDS_MAX); } + static bool proc_check_elf (uint8_t* elf) { if (!((elf[0] == 0x7F) && (elf[1] == 'E') && (elf[2] == 'L') && (elf[3] == 'F'))) return false; diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index a39fa7d..da6c72d 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -59,6 +59,12 @@ struct proc* proc_find_pid (int pid); struct proc* proc_from_file (struct procgroup* procgroup, const char* mountpoint, const char* path); +void proc_free_pid (int pid); + +int proc_alloc_pid (void); + +void proc_pid_alloc_init (void); + void proc_init (void); #endif // _KERNEL_PROC_PROC_H diff --git a/kernel/proc/procgroup.c b/kernel/proc/procgroup.c index c47b089..657198f 100644 --- a/kernel/proc/procgroup.c +++ b/kernel/proc/procgroup.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -11,9 +12,14 @@ #include #include +#define PGIDS_MAX 1024 + static struct rb_node_link* procgroup_tree = NULL; static spin_lock_t procgroup_tree_lock = SPIN_LOCK_INIT; -static atomic_int pgids = 0; + +static struct id_alloc pgid_alloc; + +void procgroup_pgid_alloc_init (void) { id_alloc_init (&pgid_alloc, PGIDS_MAX); } struct procgroup* procgroup_find (int pgid) { struct procgroup* procgroup = NULL; @@ -145,9 +151,20 @@ struct procgroup* procgroup_create (void) { memset (procgroup, 0, sizeof (*procgroup)); + if (!id_alloc_init (&procgroup->vfs_handle_id_alloc, PROCGROUP_VFS_HANDLES_MAX)) { + free (procgroup); + return NULL; + } + + procgroup->pgid = id_alloc (&pgid_alloc); + + if (procgroup->pgid < 0) { + free (procgroup); + return NULL; + } + procgroup->memb_proc_tree = NULL; procgroup->lock = SPIN_LOCK_INIT; - procgroup->pgid = atomic_fetch_add (&pgids, 1); procgroup->pd.cr3_paddr = mm_alloc_user_pd_phys (); procgroup->map_base = PROC_MAP_BASE; @@ -175,6 +192,64 @@ void procgroup_attach (struct procgroup* procgroup, struct proc* proc) { spin_unlock (&procgroup->lock); } +static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx* rctx) { + spin_lock (&procgroup_tree_lock); + spin_lock (&procgroup->lock); + + rbtree_delete (&procgroup_tree, &procgroup->procgroup_tree_link); + + spin_unlock (&procgroup->lock); + spin_unlock (&procgroup_tree_lock); + + struct list_node_link* resource_delete_list = NULL; + + /* delete resources */ + struct rb_node_link* rnode; + rbtree_first (&procgroup->resource_tree, rnode); + while (rnode) { + struct rb_node_link* next; + rbtree_next (rnode, next); + + struct proc_resource* resource = rbtree_entry (rnode, struct proc_resource, resource_tree_link); + + rnode = next; + + list_append (resource_delete_list, &resource->delete_list_link); + } + + struct list_node_link *resource_delete_link, *resource_delete_tmp_link; + list_foreach (resource_delete_list, resource_delete_link, resource_delete_tmp_link) { + struct proc_resource* resource = + list_entry (resource_delete_link, struct proc_resource, delete_list_link); + + list_remove (resource_delete_list, &resource->delete_list_link); + + proc_delete_resource (resource, rctx); + } + + /* unlock VFS owned mountpoints */ + vfs_procgroup_cleanup (procgroup); + + /* delete mappings */ + struct list_node_link *mapping_link, *mapping_link_tmp; + list_foreach (procgroup->mappings, mapping_link, mapping_link_tmp) { + struct proc_mapping* mapping = + list_entry (mapping_link, struct proc_mapping, proc_mappings_link); + + pmm_free (mapping->paddr, mapping->size / PAGE_SIZE); + free (mapping); + } + + pmm_free (procgroup->pd.cr3_paddr, 1); + + free (procgroup->tls.tls_tmpl); + + id_alloc_fini (&procgroup->vfs_handle_id_alloc); + id_free (&pgid_alloc, procgroup->pgid); + + free (procgroup); +} + void procgroup_detach (struct procgroup* procgroup, struct proc* proc, struct reschedule_ctx* rctx) { spin_lock (&procgroup->lock); @@ -187,58 +262,6 @@ void procgroup_detach (struct procgroup* procgroup, struct proc* proc, spin_unlock (&procgroup->lock); if (memb_tree == NULL) { - spin_lock (&procgroup_tree_lock); - spin_lock (&procgroup->lock); - - rbtree_delete (&procgroup_tree, &procgroup->procgroup_tree_link); - - spin_unlock (&procgroup->lock); - spin_unlock (&procgroup_tree_lock); - - struct list_node_link* resource_delete_list = NULL; - - /* delete resources */ - struct rb_node_link* rnode; - rbtree_first (&procgroup->resource_tree, rnode); - while (rnode) { - struct rb_node_link* next; - rbtree_next (rnode, next); - - struct proc_resource* resource = - rbtree_entry (rnode, struct proc_resource, resource_tree_link); - - rnode = next; - - list_append (resource_delete_list, &resource->delete_list_link); - } - - struct list_node_link *resource_delete_link, *resource_delete_tmp_link; - list_foreach (resource_delete_list, resource_delete_link, resource_delete_tmp_link) { - struct proc_resource* resource = - list_entry (resource_delete_link, struct proc_resource, delete_list_link); - - list_remove (resource_delete_list, &resource->delete_list_link); - - proc_delete_resource (resource, rctx); - } - - /* unlock VFS owned mountpoints */ - vfs_procgroup_cleanup (procgroup); - - /* delete mappings */ - struct list_node_link *mapping_link, *mapping_link_tmp; - list_foreach (procgroup->mappings, mapping_link, mapping_link_tmp) { - struct proc_mapping* mapping = - list_entry (mapping_link, struct proc_mapping, proc_mappings_link); - - pmm_free (mapping->paddr, mapping->size / PAGE_SIZE); - free (mapping); - } - - pmm_free (procgroup->pd.cr3_paddr, 1); - - free (procgroup->tls.tls_tmpl); - - free (procgroup); + procgroup_delete (procgroup, rctx); } } diff --git a/kernel/proc/procgroup.h b/kernel/proc/procgroup.h index 26cb150..323b37d 100644 --- a/kernel/proc/procgroup.h +++ b/kernel/proc/procgroup.h @@ -1,6 +1,7 @@ #ifndef _KERNEL_PROC_PROCGROUP_H #define _KERNEL_PROC_PROCGROUP_H +#include #include #include #include @@ -9,6 +10,8 @@ #include #include +#define PROCGROUP_VFS_HANDLES_MAX 256 + struct proc; struct reschedule_ctx; @@ -32,7 +35,7 @@ struct procgroup { struct procgroup_tls tls; uint64_t capabilities; struct rb_node_link* vfs_handle_tree; - int sys_vfs_handles; + struct id_alloc vfs_handle_id_alloc; }; struct procgroup* procgroup_create (void); @@ -48,4 +51,6 @@ bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t struct procgroup* procgroup_find (int pgid); +void procgroup_pgid_alloc_init (void); + #endif // _KERNEL_PROC_PROCGROUP_H