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:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
** Distributed under the terms of the OpenBeOS License.
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
*/
|
*/
|
||||||
#ifndef _KERNEL_IMAGE_H
|
#ifndef _KERNEL_IMAGE_H
|
||||||
@@ -11,16 +11,17 @@
|
|||||||
|
|
||||||
struct team;
|
struct team;
|
||||||
|
|
||||||
extern image_id register_image(team_id team, image_info *info, size_t size);
|
extern image_id register_image(struct team *team, image_info *info, size_t size);
|
||||||
extern status_t unregister_image(team_id team, image_id id);
|
extern status_t unregister_image(struct team *team, image_id id);
|
||||||
extern int32 count_images(struct team *team);
|
extern int32 count_images(struct team *team);
|
||||||
extern status_t remove_images(struct team *team);
|
extern status_t remove_images(struct team *team);
|
||||||
|
extern status_t image_init(void);
|
||||||
|
|
||||||
// user-space exported calls
|
// user-space exported calls
|
||||||
extern status_t user_unregister_image(image_id id);
|
extern status_t _user_unregister_image(image_id id);
|
||||||
extern image_id user_register_image(image_info *userInfo, size_t size);
|
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,
|
extern status_t _user_get_next_image_info(team_id team, int32 *_cookie,
|
||||||
image_info *userInfo, size_t size);
|
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_get_image_info(image_id id, image_info *userInfo, size_t size);
|
||||||
|
|
||||||
#endif /* _KRENEL_IMAGE_H */
|
#endif /* _KRENEL_IMAGE_H */
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
/* Contains the ELF loader */
|
/* 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.
|
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
** Distributed under the terms of the NewOS License.
|
** Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
@@ -12,6 +15,7 @@
|
|||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <kimage.h>
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <arch/elf.h>
|
#include <arch/elf.h>
|
||||||
@@ -1017,6 +1021,8 @@ elf_init(kernel_args *ka)
|
|||||||
area_info areaInfo;
|
area_info areaInfo;
|
||||||
struct preloaded_image *image;
|
struct preloaded_image *image;
|
||||||
|
|
||||||
|
image_init();
|
||||||
|
|
||||||
mutex_init(&image_lock, "kimages_lock");
|
mutex_init(&image_lock, "kimages_lock");
|
||||||
mutex_init(&image_load_lock, "kimages_load_lock");
|
mutex_init(&image_load_lock, "kimages_load_lock");
|
||||||
|
|
||||||
|
|||||||
+40
-42
@@ -14,6 +14,14 @@
|
|||||||
#include <string.h>
|
#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
|
// ToDo: register kernel images as well
|
||||||
|
|
||||||
struct image {
|
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.
|
/** Registers an image with the specified team.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
image_id
|
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 image *image;
|
||||||
struct team *team;
|
|
||||||
cpu_status state;
|
|
||||||
|
|
||||||
image = malloc(sizeof(image_info));
|
image = malloc(sizeof(image_info));
|
||||||
if (image == NULL)
|
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));
|
memcpy(&image->info, _info, sizeof(image_info));
|
||||||
|
|
||||||
state = disable_interrupts();
|
mutex_lock(&sImageMutex);
|
||||||
GRAB_TEAM_LOCK();
|
|
||||||
|
|
||||||
team = team_get_team_struct_locked(teamID);
|
|
||||||
if (team) {
|
|
||||||
image->info.id = id;
|
image->info.id = id;
|
||||||
list_add_item(&team->image_list, image);
|
list_add_item(&team->image_list, image);
|
||||||
}
|
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
mutex_unlock(&sImageMutex);
|
||||||
restore_interrupts(state);
|
|
||||||
|
|
||||||
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;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,19 +66,13 @@ register_image(team_id teamID, image_info *_info, size_t size)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
status_t
|
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;
|
status_t status = B_ENTRY_NOT_FOUND;
|
||||||
struct team *team;
|
|
||||||
cpu_status state;
|
|
||||||
|
|
||||||
state = disable_interrupts();
|
|
||||||
GRAB_TEAM_LOCK();
|
|
||||||
|
|
||||||
team = team_get_team_struct_locked(teamID);
|
|
||||||
if (team) {
|
|
||||||
struct image *image = NULL;
|
struct image *image = NULL;
|
||||||
|
|
||||||
|
mutex_lock(&sImageMutex);
|
||||||
|
|
||||||
while ((image = list_get_next_item(&team->image_list, image)) != NULL) {
|
while ((image = list_get_next_item(&team->image_list, image)) != NULL) {
|
||||||
if (image->info.id == id) {
|
if (image->info.id == id) {
|
||||||
list_remove_link(image);
|
list_remove_link(image);
|
||||||
@@ -85,10 +81,8 @@ unregister_image(team_id teamID, image_id id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
mutex_unlock(&sImageMutex);
|
||||||
restore_interrupts(state);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -135,16 +129,11 @@ status_t
|
|||||||
_get_image_info(image_id id, image_info *info, size_t size)
|
_get_image_info(image_id id, image_info *info, size_t size)
|
||||||
{
|
{
|
||||||
status_t status = B_ENTRY_NOT_FOUND;
|
status_t status = B_ENTRY_NOT_FOUND;
|
||||||
struct team *team;
|
struct team *team = thread_get_current_thread()->team;
|
||||||
cpu_status state;
|
|
||||||
|
|
||||||
state = disable_interrupts();
|
|
||||||
GRAB_TEAM_LOCK();
|
|
||||||
|
|
||||||
team = thread_get_current_thread()->team;
|
|
||||||
if (team) {
|
|
||||||
struct image *image = NULL;
|
struct image *image = NULL;
|
||||||
|
|
||||||
|
mutex_lock(&sImageMutex);
|
||||||
|
|
||||||
while ((image = list_get_next_item(&team->image_list, image)) != NULL) {
|
while ((image = list_get_next_item(&team->image_list, image)) != NULL) {
|
||||||
if (image->info.id == id) {
|
if (image->info.id == id) {
|
||||||
memcpy(info, &image->info, size);
|
memcpy(info, &image->info, size);
|
||||||
@@ -152,10 +141,8 @@ _get_image_info(image_id id, image_info *info, size_t size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
mutex_unlock(&sImageMutex);
|
||||||
restore_interrupts(state);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -168,6 +155,8 @@ _get_next_image_info(team_id teamID, int32 *cookie, image_info *info, size_t siz
|
|||||||
struct team *team;
|
struct team *team;
|
||||||
cpu_status state;
|
cpu_status state;
|
||||||
|
|
||||||
|
mutex_lock(&sImageMutex);
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_TEAM_LOCK();
|
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();
|
RELEASE_TEAM_LOCK();
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
|
mutex_unlock(&sImageMutex);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
image_init(void)
|
||||||
|
{
|
||||||
|
return mutex_init(&sImageMutex, "image");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
// Functions exported for the user space
|
// Functions exported for the user space
|
||||||
|
|
||||||
|
|
||||||
status_t
|
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
|
image_id
|
||||||
user_register_image(image_info *userInfo, size_t size)
|
_user_register_image(image_info *userInfo, size_t size)
|
||||||
{
|
{
|
||||||
image_info info;
|
image_info info;
|
||||||
|
|
||||||
@@ -218,12 +216,12 @@ user_register_image(image_info *userInfo, size_t size)
|
|||||||
|| user_memcpy(&info, userInfo, size) < B_OK)
|
|| user_memcpy(&info, userInfo, size) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
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
|
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;
|
image_info info;
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -244,7 +242,7 @@ user_get_image_info(image_id id, image_info *userInfo, size_t size)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
image_info info;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|||||||
@@ -391,16 +391,16 @@ syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_ret)
|
|||||||
|
|
||||||
// image calls
|
// image calls
|
||||||
case SYSCALL_REGISTER_IMAGE:
|
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;
|
break;
|
||||||
case SYSCALL_UNREGISTER_IMAGE:
|
case SYSCALL_UNREGISTER_IMAGE:
|
||||||
*call_ret = user_unregister_image((image_id)arg0);
|
*call_ret = _user_unregister_image((image_id)arg0);
|
||||||
break;
|
break;
|
||||||
case SYSCALL_GET_IMAGE_INFO:
|
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;
|
break;
|
||||||
case SYSCALL_GET_NEXT_IMAGE_INFO:
|
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;
|
break;
|
||||||
|
|
||||||
// node monitor calls
|
// node monitor calls
|
||||||
|
|||||||
Reference in New Issue
Block a user