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:
parent
fd1f6b7f01
commit
11a5baaf67
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue