Removed team::_aspace_id since it already has a direct pointer to it.

Changed the way a vm_address_space is deleted: instead of having to explicitly
call vm_delete_aspace(), the last vm_put_aspace() will remove it.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9254 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-10-07 17:11:54 +00:00
parent 894e120a01
commit 1a705b91b7
5 changed files with 48 additions and 77 deletions

View File

@ -68,7 +68,6 @@ struct team {
int pending_signals;
void *io_context;
sem_id death_sem; /* semaphore to wait on for dying threads */
aspace_id _aspace_id; /* address space pointer */
vm_address_space *aspace;
vm_address_space *kaspace;
addr_t user_env_base;

View File

@ -23,9 +23,10 @@ extern "C" {
status_t vm_init(kernel_args *ka);
status_t vm_init_postsem(struct kernel_args *ka);
status_t vm_init_postthread(struct kernel_args *ka);
status_t vm_aspace_init(void);
status_t vm_aspace_init_post_sem(void);
aspace_id vm_create_aspace(const char *name, addr base, addr size, bool kernel);
status_t vm_delete_aspace(aspace_id);
status_t vm_create_aspace(const char *name, addr base, addr size, bool kernel, vm_address_space **_aspace);
status_t vm_delete_areas(struct vm_address_space *aspace);
vm_address_space *vm_get_kernel_aspace(void);
aspace_id vm_get_kernel_aspace_id(void);

View File

@ -178,19 +178,19 @@ arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
if (t_to->user_local_storage != NULL)
set_tls_context(t_to);
if (t_from->team->_aspace_id >= 0 && t_to->team->_aspace_id >= 0) {
if (t_from->team->aspace != NULL && t_to->team->aspace != NULL) {
// they are both uspace threads
if (t_from->team->_aspace_id == t_to->team->_aspace_id) {
if (t_from->team == t_to->team) {
// dont change the pgdir, same address space
new_pgdir = NULL;
} else {
// switching to a new address space
new_pgdir = i386_translation_map_get_pgdir(&t_to->team->aspace->translation_map);
}
} else if (t_from->team->_aspace_id < 0 && t_to->team->_aspace_id < 0) {
} else if (t_from->team->aspace == NULL && t_to->team->aspace == NULL) {
// they must both be kspace threads
new_pgdir = NULL;
} else if (t_to->team->_aspace_id < 0) {
} else if (t_to->team->aspace == NULL) {
// the one we're switching to is kspace
new_pgdir = i386_translation_map_get_pgdir(&t_to->team->kaspace->translation_map);
} else {

View File

@ -2486,7 +2486,7 @@ area_id
create_area_etc(struct team *team, const char *name, void **address, uint32 addressSpec,
uint32 size, uint32 lock, uint32 protection)
{
return vm_create_anonymous_region(team->_aspace_id, (char *)name, address,
return vm_create_anonymous_region(team->aspace->id, (char *)name, address,
addressSpec, size, lock, protection);
}
@ -2522,7 +2522,7 @@ create_area(const char *name, void **_address, uint32 addressSpec, size_t size,
status_t
delete_area_etc(struct team *team, area_id area)
{
return vm_delete_region(team->_aspace_id, area);
return vm_delete_region(team->aspace->id, area);
}

View File

@ -158,10 +158,31 @@ aspace_hash(void *_a, const void *key, uint32 range)
vm_address_space *aspace = _a;
const aspace_id *id = key;
if(aspace != NULL)
return (aspace->id % range);
else
return (*id % range);
if (aspace != NULL)
return aspace->id % range;
return *id % range;
}
static void
delete_address_space(vm_address_space *aspace)
{
TRACE(("vm_delete_aspace: called on aspace 0x%lx\n", aspace->id));
// put this aspace in the deletion state
// this guarantees that no one else will add regions to the list
acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0);
aspace->state = VM_ASPACE_STATE_DELETION;
vm_delete_areas(aspace);
(*aspace->translation_map.ops->destroy)(&aspace->translation_map);
free(aspace->name);
delete_sem(aspace->virtual_map.sem);
free(aspace);
}
@ -211,10 +232,10 @@ vm_get_current_user_aspace(void)
aspace_id
vm_get_current_user_aspace_id(void)
{
struct thread *t = thread_get_current_thread();
struct thread *thread = thread_get_current_thread();
if (t)
return t->team->_aspace_id;
if (thread)
return thread->team->aspace->id;
return -1;
}
@ -241,36 +262,26 @@ vm_put_aspace(vm_address_space *aspace)
if (aspace == kernel_aspace)
panic("vm_put_aspace: tried to delete the kernel aspace!\n");
if (aspace->virtual_map.region_list)
panic("vm_put_aspace: aspace at %p has zero ref count, but region list isn't empty!\n", aspace);
(*aspace->translation_map.ops->destroy)(&aspace->translation_map);
free(aspace->name);
delete_sem(aspace->virtual_map.sem);
free(aspace);
return;
delete_address_space(aspace);
}
aspace_id
vm_create_aspace(const char *name, addr_t base, addr_t size, bool kernel)
status_t
vm_create_aspace(const char *name, addr_t base, addr_t size, bool kernel, vm_address_space **_aspace)
{
vm_address_space *aspace;
int err;
status_t err;
aspace = (vm_address_space *)malloc(sizeof(vm_address_space));
if (aspace == NULL)
return ENOMEM;
return B_NO_MEMORY;
TRACE(("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", name, size, base, aspace));
aspace->name = (char *)malloc(strlen(name) + 1);
if (aspace->name == NULL ) {
free(aspace);
return ENOMEM;
return B_NO_MEMORY;
}
strcpy(aspace->name, name);
@ -286,7 +297,7 @@ vm_create_aspace(const char *name, addr_t base, addr_t size, bool kernel)
// initialize the corresponding translation map
err = vm_translation_map_create(&aspace->translation_map, kernel);
if (err < 0) {
if (err < B_OK) {
free(aspace->name);
free(aspace);
return err;
@ -306,42 +317,8 @@ vm_create_aspace(const char *name, addr_t base, addr_t size, bool kernel)
hash_insert(aspace_table, aspace);
release_sem_etc(aspace_hash_sem, WRITE_COUNT, 0);
return aspace->id;
}
status_t
vm_delete_aspace(aspace_id aid)
{
vm_address_space *aspace;
aspace = vm_get_aspace_by_id(aid);
if (aspace == NULL)
return ERR_VM_INVALID_ASPACE;
TRACE(("vm_delete_aspace: called on aspace 0x%lx\n", aid));
// put this aspace in the deletion state
// this guarantees that no one else will add regions to the list
acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0);
if (aspace->state == VM_ASPACE_STATE_DELETION) {
// abort, someone else is already deleting this aspace
release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0);
vm_put_aspace(aspace);
return B_NO_ERROR;
}
aspace->state = VM_ASPACE_STATE_DELETION;
vm_delete_areas(aspace);
// unlock
release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0);
// release two refs on the address space
vm_put_aspace(aspace);
vm_put_aspace(aspace);
return B_NO_ERROR;
*_aspace = aspace;
return B_OK;
}
@ -385,14 +362,8 @@ vm_aspace_init(void)
kernel_aspace = NULL;
// create the initial kernel address space
{
aspace_id aid;
aid = vm_create_aspace("kernel_land", KERNEL_BASE, KERNEL_SIZE, true);
if (aid < 0)
panic("vm_init: error creating kernel address space!\n");
kernel_aspace = vm_get_aspace_by_id(aid);
vm_put_aspace(kernel_aspace);
}
if (vm_create_aspace("kernel_land", KERNEL_BASE, KERNEL_SIZE, true, &kernel_aspace) != B_OK)
panic("vm_init: error creating kernel address space!\n");
add_debugger_command("aspaces", &dump_aspace_list, "Dump a list of all address spaces");
add_debugger_command("aspace", &dump_aspace, "Dump info about a particular address space");