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:
parent
894e120a01
commit
1a705b91b7
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user