From 1a705b91b7d92c80827403194f45b28e8659e24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 7 Oct 2004 17:11:54 +0000 Subject: [PATCH] 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 --- headers/private/kernel/thread_types.h | 1 - headers/private/kernel/vm.h | 5 +- src/kernel/core/arch/x86/arch_thread.c | 8 +- src/kernel/core/vm/vm.c | 4 +- src/kernel/core/vm/vm_address_space.c | 107 +++++++++---------------- 5 files changed, 48 insertions(+), 77 deletions(-) diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 9a30aedd15..4fef5d1478 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -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; diff --git a/headers/private/kernel/vm.h b/headers/private/kernel/vm.h index 32549c6ff0..e52d7c53bd 100755 --- a/headers/private/kernel/vm.h +++ b/headers/private/kernel/vm.h @@ -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); diff --git a/src/kernel/core/arch/x86/arch_thread.c b/src/kernel/core/arch/x86/arch_thread.c index 78401b06f8..f04f39f81a 100755 --- a/src/kernel/core/arch/x86/arch_thread.c +++ b/src/kernel/core/arch/x86/arch_thread.c @@ -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 { diff --git a/src/kernel/core/vm/vm.c b/src/kernel/core/vm/vm.c index 8d6c6ad0fe..c5c986b409 100755 --- a/src/kernel/core/vm/vm.c +++ b/src/kernel/core/vm/vm.c @@ -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); } diff --git a/src/kernel/core/vm/vm_address_space.c b/src/kernel/core/vm/vm_address_space.c index 6b87356ab5..7fc8a2a6e8 100644 --- a/src/kernel/core/vm/vm_address_space.c +++ b/src/kernel/core/vm/vm_address_space.c @@ -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");