Now other code accounts for reserved regions in the standard region_list as well.

Introduced RESERVED_REGION_ID definition.
Some minor cleanups.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7886 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-06-10 02:03:55 +00:00
parent c9df0d11c8
commit fab1cad1b8
2 changed files with 109 additions and 70 deletions
+50 -21
View File
@@ -82,14 +82,16 @@ static vm_region *vm_virtual_map_lookup(vm_virtual_map *map, addr_t address);
//static void vm_region_release_ref(vm_region *region); //static void vm_region_release_ref(vm_region *region);
//static void vm_region_release_ref2(vm_region *region); //static void vm_region_release_ref2(vm_region *region);
static int region_compare(void *_r, const void *key)
static int
region_compare(void *_r, const void *key)
{ {
vm_region *r = _r; vm_region *r = _r;
const region_id *id = key; const region_id *id = key;
if (r->id == *id) if (r->id == *id)
return 0; return 0;
else
return -1; return -1;
} }
@@ -101,9 +103,9 @@ region_hash(void *_r, const void *key, uint32 range)
const region_id *id = key; const region_id *id = key;
if (r != NULL) if (r != NULL)
return (r->id % range); return r->id % range;
else
return (*id % range); return *id % range;
} }
@@ -115,7 +117,7 @@ aspace_compare(void *_a, const void *key)
if (aspace->id == *id) if (aspace->id == *id)
return 0; return 0;
else
return -1; return -1;
} }
@@ -171,12 +173,15 @@ region_id vm_find_region_by_name(aspace_id aid, const char *name)
acquire_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0, 0); acquire_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0, 0);
region = aspace->virtual_map.region_list; region = aspace->virtual_map.region_list;
while(region != NULL) { for (; region != NULL; region = region->aspace_next) {
// ignore reserved space regions
if (region->id == RESERVED_REGION_ID)
continue;
if (strcmp(region->name, name) == 0) { if (strcmp(region->name, name) == 0) {
id = region->id; id = region->id;
break; break;
} }
region = region->aspace_next;
} }
release_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0); release_sem_etc(aspace->virtual_map.sem, READ_COUNT, 0);
@@ -193,7 +198,7 @@ _vm_create_reserved_region_struct(vm_virtual_map *map)
return NULL; return NULL;
memset(reserved, 0, sizeof(vm_region)); memset(reserved, 0, sizeof(vm_region));
reserved->id = -1; reserved->id = RESERVED_REGION_ID;
// this marks it as reserved space // this marks it as reserved space
reserved->map = map; reserved->map = map;
@@ -251,7 +256,7 @@ find_reserved_region(vm_virtual_map *map, addr_t start, addr_t size, vm_region *
while (next) { while (next) {
if (next->base <= start && next->base + next->size >= start + size) { if (next->base <= start && next->base + next->size >= start + size) {
// this region covers the requested range // this region covers the requested range
if (next->id != -1) { if (next->id != RESERVED_REGION_ID) {
// but it's not reserved space, it's a real region // but it's not reserved space, it's a real region
return ERR_VM_NO_REGION_SLOT; return ERR_VM_NO_REGION_SLOT;
} }
@@ -648,7 +653,7 @@ vm_unreserve_address_range(aspace_id aid, void *address, addr_t size)
area = addressSpace->virtual_map.region_list; area = addressSpace->virtual_map.region_list;
while (area) { while (area) {
// the region must be completely part of the reserved range // the region must be completely part of the reserved range
if (area->id == -1 && area->base >= (addr_t)address if (area->id == RESERVED_REGION_ID && area->base >= (addr_t)address
&& area->base + area->size <= (addr_t)address + size) { && area->base + area->size <= (addr_t)address + size) {
// remove reserved range // remove reserved range
vm_region *reserved = area; vm_region *reserved = area;
@@ -1130,7 +1135,7 @@ vm_clone_region(aspace_id aid, char *name, void **address, int addr_type,
if (err < 0) if (err < 0)
return err; return err;
else
return new_region->id; return new_region->id;
} }
@@ -1191,6 +1196,10 @@ _vm_put_region(vm_region *region, bool aspace_locked)
vm_address_space *aspace; vm_address_space *aspace;
bool removeit = false; bool removeit = false;
// we should never get here, but if we do, we can handle it
if (region->id == RESERVED_REGION_ID)
return;
acquire_sem_etc(region_hash_sem, WRITE_COUNT, 0, 0); acquire_sem_etc(region_hash_sem, WRITE_COUNT, 0, 0);
if (atomic_add(&region->ref_count, -1) == 1) { if (atomic_add(&region->ref_count, -1) == 1) {
hash_remove(region_table, region); hash_remove(region_table, region);
@@ -1239,7 +1248,6 @@ _vm_put_region(vm_region *region, bool aspace_locked)
// now we can give up the last ref to the aspace // now we can give up the last ref to the aspace
vm_put_aspace(aspace); vm_put_aspace(aspace);
if(region->name)
free(region->name); free(region->name);
free(region); free(region);
@@ -1512,17 +1520,21 @@ dump_region(int argc, char **argv)
region_id region_id
find_region_by_address(addr_t vaddress) find_region_by_address(addr_t address)
{ {
vm_address_space *aspace; vm_address_space *aspace;
vm_region *region; vm_region *region;
region_id result = B_ERROR; region_id result = B_ERROR;
aspace = vm_get_current_user_aspace(); aspace = vm_get_current_user_aspace();
for(region = aspace->virtual_map.region_list; region != NULL; region = region->aspace_next) for (region = aspace->virtual_map.region_list; region != NULL; region = region->aspace_next) {
{ if (region->id == RESERVED_REGION_ID)
if ((vaddress>=region->base) && (vaddress<=(region->base+region->size))) continue;
if (address >= region->base && address <= region->base + region->size) {
result = region->id; result = region->id;
break;
}
} }
vm_put_aspace(aspace); vm_put_aspace(aspace);
return result; return result;
@@ -1802,6 +1814,13 @@ vm_delete_aspace(aspace_id aid)
region = aspace->virtual_map.region_list; region = aspace->virtual_map.region_list;
while (region) { while (region) {
next = region->aspace_next; next = region->aspace_next;
if (region->id == RESERVED_REGION_ID) {
// just remove it
free(region);
region = next;
continue;
}
// decrement the ref on this region, may actually push the ref < 0, but that's okay // decrement the ref on this region, may actually push the ref < 0, but that's okay
_vm_put_region(region, true); _vm_put_region(region, true);
region = next; region = next;
@@ -2103,7 +2122,8 @@ forbid_page_faults(void)
} }
int vm_page_fault(addr_t address, addr_t fault_address, bool is_write, bool is_user, addr_t *newip) int
vm_page_fault(addr_t address, addr_t fault_address, bool is_write, bool is_user, addr_t *newip)
{ {
int err; int err;
@@ -2443,6 +2463,9 @@ vm_virtual_map_lookup(vm_virtual_map *map, addr_t address)
return region; return region;
for (region = map->region_list; region != NULL; region = region->aspace_next) { for (region = map->region_list; region != NULL; region = region->aspace_next) {
if (region->id == RESERVED_REGION_ID)
continue;
if (region->base <= address && (region->base + region->size) > address) if (region->base <= address && (region->base + region->size) > address)
break; break;
} }
@@ -2452,17 +2475,23 @@ vm_virtual_map_lookup(vm_virtual_map *map, addr_t address)
return region; return region;
} }
int vm_get_physical_page(addr_t paddr, addr_t *vaddr, int flags)
int
vm_get_physical_page(addr_t paddr, addr_t *vaddr, int flags)
{ {
return (*kernel_aspace->translation_map.ops->get_physical_page)(paddr, vaddr, flags); return (*kernel_aspace->translation_map.ops->get_physical_page)(paddr, vaddr, flags);
} }
int vm_put_physical_page(addr_t vaddr)
int
vm_put_physical_page(addr_t vaddr)
{ {
return (*kernel_aspace->translation_map.ops->put_physical_page)(vaddr); return (*kernel_aspace->translation_map.ops->put_physical_page)(vaddr);
} }
void vm_increase_max_commit(addr_t delta)
void
vm_increase_max_commit(addr_t delta)
{ {
int state; int state;
+11 -1
View File
@@ -2,6 +2,7 @@
** 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.
*/ */
#include <kernel.h> #include <kernel.h>
#include <thread.h> #include <thread.h>
#include <debug.h> #include <debug.h>
@@ -17,7 +18,9 @@ bool trimming_cycle;
static addr free_memory_low_water; static addr free_memory_low_water;
static addr free_memory_high_water; static addr free_memory_high_water;
static void scan_pages(vm_address_space *aspace, addr free_target)
static void
scan_pages(vm_address_space *aspace, addr free_target)
{ {
vm_region *first_region; vm_region *first_region;
vm_region *region; vm_region *region;
@@ -46,6 +49,12 @@ static void scan_pages(vm_address_space *aspace, addr free_target)
region = first_region; region = first_region;
for (;;) { for (;;) {
// ignore reserved ranges
while (region != NULL && region->id == RESERVED_REGION_ID)
region = region->aspace_next;
if (region == NULL)
break;
// scan the pages in this region // scan the pages in this region
mutex_lock(&region->cache_ref->lock); mutex_lock(&region->cache_ref->lock);
if (!region->cache_ref->cache->scan_skip) { if (!region->cache_ref->cache->scan_skip) {
@@ -121,6 +130,7 @@ static void scan_pages(vm_address_space *aspace, addr free_target)
// dprintf("exiting scan_pages\n"); // dprintf("exiting scan_pages\n");
} }
static int32 static int32
page_daemon(void *unused) page_daemon(void *unused)
{ {