diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index f1f4949..ac69bee 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -100,6 +100,12 @@ int vfs_open (struct procgroup* procgroup, const char* mountpoint, const char* p int id = handle->id = id_alloc (&procgroup->vfs_handle_id_alloc); + if (id < 0) { + free (handle); + spin_unlock (&procgroup->lock); + return -ST_OOM_ERROR; + } + rbtree_insert (struct vfs_handle, &procgroup->vfs_handle_tree, &handle->handle_tree_link, handle_tree_link, id); diff --git a/kernel/proc/procgroup.c b/kernel/proc/procgroup.c index 657198f..743f557 100644 --- a/kernel/proc/procgroup.c +++ b/kernel/proc/procgroup.c @@ -156,9 +156,17 @@ struct procgroup* procgroup_create (void) { return NULL; } + if (!id_alloc_init (&procgroup->rid_alloc, PROCGROUP_RESOURCES_MAX)) { + id_alloc_fini (&procgroup->vfs_handle_id_alloc); + free (procgroup); + return NULL; + } + procgroup->pgid = id_alloc (&pgid_alloc); if (procgroup->pgid < 0) { + id_alloc_fini (&procgroup->rid_alloc); + id_alloc_fini (&procgroup->vfs_handle_id_alloc); free (procgroup); return NULL; } @@ -168,7 +176,9 @@ struct procgroup* procgroup_create (void) { procgroup->pd.cr3_paddr = mm_alloc_user_pd_phys (); procgroup->map_base = PROC_MAP_BASE; - if (proc_create_resource_mail (procgroup, 1) == NULL) { + if (proc_create_resource_mail (procgroup) == NULL) { + id_alloc_fini (&procgroup->rid_alloc); + id_alloc_fini (&procgroup->vfs_handle_id_alloc); free (procgroup); return NULL; } @@ -224,7 +234,7 @@ static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx list_remove (resource_delete_list, &resource->delete_list_link); - proc_delete_resource (resource, rctx); + proc_delete_resource (procgroup, resource, rctx); } /* unlock VFS owned mountpoints */ @@ -245,6 +255,7 @@ static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx free (procgroup->tls.tls_tmpl); id_alloc_fini (&procgroup->vfs_handle_id_alloc); + id_alloc_fini (&procgroup->rid_alloc); id_free (&pgid_alloc, procgroup->pgid); free (procgroup); diff --git a/kernel/proc/procgroup.h b/kernel/proc/procgroup.h index 323b37d..c06d67f 100644 --- a/kernel/proc/procgroup.h +++ b/kernel/proc/procgroup.h @@ -11,6 +11,7 @@ #include #define PROCGROUP_VFS_HANDLES_MAX 256 +#define PROCGROUP_RESOURCES_MAX 256 struct proc; struct reschedule_ctx; @@ -29,6 +30,7 @@ struct procgroup { struct rb_node_link* memb_proc_tree; spin_lock_t lock; struct rb_node_link* resource_tree; + struct id_alloc rid_alloc; struct pd pd; struct list_node_link* mappings; uintptr_t map_base; diff --git a/kernel/proc/resource.c b/kernel/proc/resource.c index 0cc8b06..0855158 100644 --- a/kernel/proc/resource.c +++ b/kernel/proc/resource.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -25,64 +26,87 @@ struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid) return resource; } -struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup, int rid) { +struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) { struct proc_resource* resource; - resource = proc_find_resource (procgroup, rid); - if (resource != NULL) - return resource; - resource = malloc (sizeof (*resource)); if (resource == NULL) return NULL; memset (resource, 0, sizeof (*resource)); - resource->lock = SPIN_LOCK_INIT; - resource->ops.cleanup = &proc_cleanup_resource_mutex; - resource->u.mutex.resource = resource; - resource->rid = rid; - resource->type = PR_MUTEX; spin_lock (&procgroup->lock); - rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, - resource_tree_link, rid); - spin_unlock (&procgroup->lock); - return resource; -} + resource->rid = id_alloc (&procgroup->rid_alloc); -struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, int rid) { - struct proc_resource* resource; - - resource = proc_find_resource (procgroup, rid); - if (resource != NULL) - return resource; - - resource = malloc (sizeof (*resource)); - if (resource == NULL) - return NULL; - - memset (resource, 0, sizeof (*resource)); - resource->lock = SPIN_LOCK_INIT; - resource->ops.cleanup = &proc_cleanup_resource_mail; - resource->u.mail.resource = resource; - resource->rid = rid; - resource->type = PR_MAIL; - - if (!ringbuffer_init (&resource->u.mail.ringbuffer, PROC_MAIL_MAX, sizeof (struct mail_packet))) { + if (resource->rid < 0) { free (resource); + spin_unlock (&procgroup->lock); return NULL; } - spin_lock (&procgroup->lock); + resource->lock = SPIN_LOCK_INIT; + resource->ops.cleanup = &proc_cleanup_resource_mutex; + resource->u.mutex.resource = resource; + resource->type = PR_MUTEX; + rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, resource_tree_link, rid); + spin_unlock (&procgroup->lock); return resource; } -void proc_delete_resource (struct proc_resource* resource, struct reschedule_ctx* rctx) { +struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) { + struct proc_resource* resource; + + resource = malloc (sizeof (*resource)); + if (resource == NULL) + return NULL; + + memset (resource, 0, sizeof (*resource)); + + spin_lock (&procgroup->lock); + + resource->rid = id_alloc (&procgroup->rid_alloc); + + if (resource->rid < 0) { + free (resource); + spin_unlock (&procgroup->lock); + return NULL; + } + + resource->lock = SPIN_LOCK_INIT; + resource->ops.cleanup = &proc_cleanup_resource_mail; + resource->u.mail.resource = resource; + resource->type = PR_MAIL; + + if (!ringbuffer_init (&resource->u.mail.ringbuffer, PROC_MAIL_MAX, sizeof (struct mail_packet))) { + id_free (&procgroup->rid_alloc, resource->rid); + free (resource); + spin_unlock (&procgroup->lock); + return NULL; + } + + rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, + resource_tree_link, rid); + + spin_unlock (&procgroup->lock); + + return resource; +} + +void proc_delete_resource (struct procgroup* procgroup, struct proc_resource* resource, + struct reschedule_ctx* rctx) { + spin_lock (&procgroup->lock); + spin_lock (&resource->lock); + + id_free (&procgroup->rid_alloc, resource->rid); + + spin_unlock (&resource->lock); + spin_unlock (&procgroup->lock); + resource->ops.cleanup (resource, rctx); free (resource); } diff --git a/kernel/proc/resource.h b/kernel/proc/resource.h index 94fdeb7..9bc038d 100644 --- a/kernel/proc/resource.h +++ b/kernel/proc/resource.h @@ -33,10 +33,11 @@ struct proc_resource { struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid); -struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup, int rid); +struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup); -struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, int rid); +struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup); -void proc_delete_resource (struct proc_resource* resource, struct reschedule_ctx* rctx); +void proc_delete_resource (struct procgroup* procgroup, struct proc_resource* resource, + struct reschedule_ctx* rctx); #endif // _KERNEL_PROC_RESOURCE_H diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 40b46ae..5722e51 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -113,11 +113,9 @@ DEFINE_SYSCALL (sys_sched) { return SYSRESULT (ST_OK); } -/* int mutex_create (int mutex_rid) */ +/* int mutex_create (void) */ DEFINE_SYSCALL (sys_mutex_create) { - int mutex_rid = (int)a1; - - struct proc_resource* mutex_resource = proc_create_resource_mutex (proc->procgroup, mutex_rid); + struct proc_resource* mutex_resource = proc_create_resource_mutex (proc->procgroup); if (mutex_resource == NULL) return SYSRESULT (-ST_OOM_ERROR); @@ -134,7 +132,7 @@ DEFINE_SYSCALL (sys_mutex_delete) { if (mutex_resource == NULL) return SYSRESULT (-ST_NOT_FOUND); - proc_delete_resource (mutex_resource, rctx); + proc_delete_resource (proc->procgroup, mutex_resource, rctx); return SYSRESULT (ST_OK); } @@ -183,7 +181,7 @@ DEFINE_SYSCALL (sys_mail_send) { if (procgroup == NULL) return SYSRESULT (-ST_NOT_FOUND); - struct proc_resource* mail_resource = proc_find_resource (procgroup, 1); + struct proc_resource* mail_resource = proc_find_resource (procgroup, 0); if (mail_resource == NULL) return SYSRESULT (-ST_NOT_FOUND); @@ -203,7 +201,7 @@ DEFINE_SYSCALL (sys_mail_receive) { if (mesg == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - struct proc_resource* mail_resource = proc_find_resource (proc->procgroup, 1); + struct proc_resource* mail_resource = proc_find_resource (proc->procgroup, 0); if (mail_resource == NULL) return SYSRESULT (-ST_NOT_FOUND); diff --git a/liballoc/liballoc.c b/liballoc/liballoc.c index cbbe8d6..c9b477b 100644 --- a/liballoc/liballoc.c +++ b/liballoc/liballoc.c @@ -4,15 +4,15 @@ #include #include -#define LIBALLOC_MUTEX 500 +int liballoc_mutex; -void liballoc_init (void) { mutex_create (LIBALLOC_MUTEX); } +void liballoc_init (void) { liballoc_mutex = mutex_create (); } -void liballoc_deinit (void) { mutex_delete (LIBALLOC_MUTEX); } +void liballoc_deinit (void) { mutex_delete (liballoc_mutex); } -int liballoc_lock (void) { return mutex_lock (LIBALLOC_MUTEX); } +int liballoc_lock (void) { return mutex_lock (liballoc_mutex); } -int liballoc_unlock (void) { return mutex_unlock (LIBALLOC_MUTEX); } +int liballoc_unlock (void) { return mutex_unlock (liballoc_mutex); } void* liballoc_alloc (int pages) { return map (0, pages, MAP_FLAGS | MAP_RW); } diff --git a/libsystem/system.c b/libsystem/system.c index 2fd48f4..01c2cdb 100644 --- a/libsystem/system.c +++ b/libsystem/system.c @@ -25,7 +25,7 @@ int clone (uintptr_t vstack_top, void (*entry) (void), void* argument_ptr) { return do_syscall (SYS_CLONE, vstack_top, entry, argument_ptr); } -int mutex_create (int mutex_rid) { return do_syscall (SYS_MUTEX_CREATE, mutex_rid); } +int mutex_create (void) { return do_syscall (SYS_MUTEX_CREATE, 0); } int mutex_delete (int mutex_rid) { return do_syscall (SYS_MUTEX_DELETE, mutex_rid); } diff --git a/libsystem/system.h b/libsystem/system.h index f84fa79..fd4bec6 100644 --- a/libsystem/system.h +++ b/libsystem/system.h @@ -33,7 +33,7 @@ int unmap (uintptr_t vaddr, size_t pages); int clone (uintptr_t vstack_top, void (*entry) (void), void* argument_ptr); /* Create a mutex */ -int mutex_create (int mutex_rid); +int mutex_create (void); /* Delete a mutex. Will wake up waiters */ int mutex_delete (int mutex_rid);