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:
+50
-21
@@ -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(®ion->ref_count, -1) == 1) {
|
if (atomic_add(®ion->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;
|
||||||
|
|
||||||
|
|||||||
@@ -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(®ion->cache_ref->lock);
|
mutex_lock(®ion->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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user