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
This commit is contained in:
Axel Dörfler 2004-05-11 15:04:36 +00:00
parent fd1f6b7f01
commit 11a5baaf67
4 changed files with 72 additions and 67 deletions

View File

@ -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 */

View File

@ -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 <vm.h>
#include <thread.h>
#include <debug.h>
#include <kimage.h>
#include <arch/cpu.h>
#include <arch/elf.h>
@ -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");

View File

@ -14,6 +14,14 @@
#include <string.h>
//#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;

View File

@ -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