From 11a5baaf6797803ff7759122d9dde907ea6dccaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 11 May 2004 15:04:36 +0000 Subject: [PATCH] Updated the private kernel image API to be more efficient (no longer needs to acquire the team spinlock). Renamed the user syscalls to the new style. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7521 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/kimage.h | 17 ++--- src/kernel/core/elf.c | 6 ++ src/kernel/core/image.c | 108 ++++++++++++++++---------------- src/kernel/core/syscalls.c | 8 +-- 4 files changed, 72 insertions(+), 67 deletions(-) diff --git a/headers/private/kernel/kimage.h b/headers/private/kernel/kimage.h index aa345bca08..9b211de6e6 100644 --- a/headers/private/kernel/kimage.h +++ b/headers/private/kernel/kimage.h @@ -1,5 +1,5 @@ /* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ #ifndef _KERNEL_IMAGE_H @@ -11,16 +11,17 @@ struct team; -extern image_id register_image(team_id team, image_info *info, size_t size); -extern status_t unregister_image(team_id team, image_id id); +extern image_id register_image(struct team *team, image_info *info, size_t size); +extern status_t unregister_image(struct team *team, image_id id); extern int32 count_images(struct team *team); extern status_t remove_images(struct team *team); +extern status_t image_init(void); // user-space exported calls -extern status_t user_unregister_image(image_id id); -extern image_id user_register_image(image_info *userInfo, size_t size); -extern status_t user_get_next_image_info(team_id team, int32 *_cookie, - image_info *userInfo, size_t size); -extern status_t user_get_image_info(image_id id, image_info *userInfo, size_t size); +extern status_t _user_unregister_image(image_id id); +extern image_id _user_register_image(image_info *userInfo, size_t size); +extern status_t _user_get_next_image_info(team_id team, int32 *_cookie, + image_info *userInfo, size_t size); +extern status_t _user_get_image_info(image_id id, image_info *userInfo, size_t size); #endif /* _KRENEL_IMAGE_H */ diff --git a/src/kernel/core/elf.c b/src/kernel/core/elf.c index e581b81385..2ea65ff738 100644 --- a/src/kernel/core/elf.c +++ b/src/kernel/core/elf.c @@ -1,6 +1,9 @@ /* Contains the ELF loader */ /* +** Copyright 2002-2004, The OpenBeOS Team. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +** ** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Distributed under the terms of the NewOS License. */ @@ -12,6 +15,7 @@ #include #include #include +#include #include #include @@ -1017,6 +1021,8 @@ elf_init(kernel_args *ka) area_info areaInfo; struct preloaded_image *image; + image_init(); + mutex_init(&image_lock, "kimages_lock"); mutex_init(&image_load_lock, "kimages_load_lock"); diff --git a/src/kernel/core/image.c b/src/kernel/core/image.c index 343ee75959..b333464586 100644 --- a/src/kernel/core/image.c +++ b/src/kernel/core/image.c @@ -14,6 +14,14 @@ #include +//#define TRACE_IMAGE +#ifdef TRACE_IMAGE +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + // ToDo: register kernel images as well struct image { @@ -23,19 +31,18 @@ struct image { }; -static image_id gNextImageID = 1; +static image_id sNextImageID = 1; +static mutex sImageMutex; /** Registers an image with the specified team. */ image_id -register_image(team_id teamID, image_info *_info, size_t size) +register_image(struct team *team, image_info *_info, size_t size) { - image_id id = atomic_add(&gNextImageID, 1); + image_id id = atomic_add(&sNextImageID, 1); struct image *image; - struct team *team; - cpu_status state; image = malloc(sizeof(image_info)); if (image == NULL) @@ -43,19 +50,14 @@ register_image(team_id teamID, image_info *_info, size_t size) memcpy(&image->info, _info, sizeof(image_info)); - state = disable_interrupts(); - GRAB_TEAM_LOCK(); + mutex_lock(&sImageMutex); - team = team_get_team_struct_locked(teamID); - if (team) { - image->info.id = id; - list_add_item(&team->image_list, image); - } + image->info.id = id; + list_add_item(&team->image_list, image); - RELEASE_TEAM_LOCK(); - restore_interrupts(state); + mutex_unlock(&sImageMutex); - dprintf("register_image(team = %ld, image id = %ld, image = %p\n", teamID, id, image); + TRACE(("register_image(team = %p, image id = %ld, image = %p\n", team, id, image)); return id; } @@ -64,31 +66,23 @@ register_image(team_id teamID, image_info *_info, size_t size) */ status_t -unregister_image(team_id teamID, image_id id) +unregister_image(struct team *team, image_id id) { status_t status = B_ENTRY_NOT_FOUND; - struct team *team; - cpu_status state; + struct image *image = NULL; - state = disable_interrupts(); - GRAB_TEAM_LOCK(); + mutex_lock(&sImageMutex); - team = team_get_team_struct_locked(teamID); - if (team) { - struct image *image = NULL; - - while ((image = list_get_next_item(&team->image_list, image)) != NULL) { - if (image->info.id == id) { - list_remove_link(image); - free(image); - status = B_OK; - break; - } + while ((image = list_get_next_item(&team->image_list, image)) != NULL) { + if (image->info.id == id) { + list_remove_link(image); + free(image); + status = B_OK; + break; } } - RELEASE_TEAM_LOCK(); - restore_interrupts(state); + mutex_unlock(&sImageMutex); return status; } @@ -135,27 +129,20 @@ status_t _get_image_info(image_id id, image_info *info, size_t size) { status_t status = B_ENTRY_NOT_FOUND; - struct team *team; - cpu_status state; + struct team *team = thread_get_current_thread()->team; + struct image *image = NULL; - state = disable_interrupts(); - GRAB_TEAM_LOCK(); + mutex_lock(&sImageMutex); - team = thread_get_current_thread()->team; - if (team) { - struct image *image = NULL; - - while ((image = list_get_next_item(&team->image_list, image)) != NULL) { - if (image->info.id == id) { - memcpy(info, &image->info, size); - status = B_OK; - break; - } + while ((image = list_get_next_item(&team->image_list, image)) != NULL) { + if (image->info.id == id) { + memcpy(info, &image->info, size); + status = B_OK; + break; } } - RELEASE_TEAM_LOCK(); - restore_interrupts(state); + mutex_unlock(&sImageMutex); return status; } @@ -168,6 +155,8 @@ _get_next_image_info(team_id teamID, int32 *cookie, image_info *info, size_t siz struct team *team; cpu_status state; + mutex_lock(&sImageMutex); + state = disable_interrupts(); GRAB_TEAM_LOCK(); @@ -191,23 +180,32 @@ _get_next_image_info(team_id teamID, int32 *cookie, image_info *info, size_t siz RELEASE_TEAM_LOCK(); restore_interrupts(state); + mutex_unlock(&sImageMutex); + return status; } +status_t +image_init(void) +{ + return mutex_init(&sImageMutex, "image"); +} + + // #pragma mark - // Functions exported for the user space status_t -user_unregister_image(image_id id) +_user_unregister_image(image_id id) { - return unregister_image(team_get_current_team_id(), id); + return unregister_image(thread_get_current_thread()->team, id); } image_id -user_register_image(image_info *userInfo, size_t size) +_user_register_image(image_info *userInfo, size_t size) { image_info info; @@ -218,12 +216,12 @@ user_register_image(image_info *userInfo, size_t size) || user_memcpy(&info, userInfo, size) < B_OK) return B_BAD_ADDRESS; - return register_image(team_get_current_team_id(), &info, size); + return register_image(thread_get_current_thread()->team, &info, size); } status_t -user_get_image_info(image_id id, image_info *userInfo, size_t size) +_user_get_image_info(image_id id, image_info *userInfo, size_t size) { image_info info; status_t status; @@ -244,7 +242,7 @@ user_get_image_info(image_id id, image_info *userInfo, size_t size) status_t -user_get_next_image_info(team_id team, int32 *_cookie, image_info *userInfo, size_t size) +_user_get_next_image_info(team_id team, int32 *_cookie, image_info *userInfo, size_t size) { image_info info; status_t status; diff --git a/src/kernel/core/syscalls.c b/src/kernel/core/syscalls.c index 818372e0fd..0bce01ce52 100644 --- a/src/kernel/core/syscalls.c +++ b/src/kernel/core/syscalls.c @@ -391,16 +391,16 @@ syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_ret) // image calls case SYSCALL_REGISTER_IMAGE: - *call_ret = user_register_image((image_info *)arg0, (size_t)arg1); + *call_ret = _user_register_image((image_info *)arg0, (size_t)arg1); break; case SYSCALL_UNREGISTER_IMAGE: - *call_ret = user_unregister_image((image_id)arg0); + *call_ret = _user_unregister_image((image_id)arg0); break; case SYSCALL_GET_IMAGE_INFO: - *call_ret = user_get_image_info((image_id)arg0, (image_info *)arg1, (size_t)arg2); + *call_ret = _user_get_image_info((image_id)arg0, (image_info *)arg1, (size_t)arg2); break; case SYSCALL_GET_NEXT_IMAGE_INFO: - *call_ret = user_get_next_image_info((team_id)arg0, (int32 *)arg1, (image_info *)arg2, (size_t)arg3); + *call_ret = _user_get_next_image_info((team_id)arg0, (int32 *)arg1, (image_info *)arg2, (size_t)arg3); break; // node monitor calls