Removed the broken vm_resize_region() and implemented it properly in resize_area(),
some ToDo-items are left. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9260 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+69
-53
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2002-2004, The OpenBeOS Team. All rights reserved.
|
** Copyright 2002-2004, The Haiku Team. All rights reserved.
|
||||||
** Distributed under the terms of the OpenBeOS License.
|
** Distributed under the terms of the Haiku License.
|
||||||
**
|
**
|
||||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
** Distributed under the terms of the NewOS License.
|
** Distributed under the terms of the NewOS License.
|
||||||
@@ -73,9 +73,6 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store, void **v
|
|||||||
off_t offset, addr_t size, int addr_type, int wiring, int lock, int mapping, vm_region **_region, const char *region_name);
|
off_t offset, addr_t size, int addr_type, int wiring, int lock, int mapping, vm_region **_region, const char *region_name);
|
||||||
static int vm_soft_fault(addr_t address, bool is_write, bool is_user);
|
static int vm_soft_fault(addr_t address, bool is_write, bool is_user);
|
||||||
static vm_region *vm_virtual_map_lookup(vm_virtual_map *map, addr_t address);
|
static vm_region *vm_virtual_map_lookup(vm_virtual_map *map, addr_t address);
|
||||||
//static int vm_region_acquire_ref(vm_region *region);
|
|
||||||
//static void vm_region_release_ref(vm_region *region);
|
|
||||||
//static void vm_region_release_ref2(vm_region *region);
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -110,9 +107,11 @@ vm_get_region_by_id(region_id rid)
|
|||||||
vm_region *region;
|
vm_region *region;
|
||||||
|
|
||||||
acquire_sem_etc(region_hash_sem, READ_COUNT, 0, 0);
|
acquire_sem_etc(region_hash_sem, READ_COUNT, 0, 0);
|
||||||
|
|
||||||
region = hash_lookup(region_table, &rid);
|
region = hash_lookup(region_table, &rid);
|
||||||
if(region)
|
if (region)
|
||||||
atomic_add(®ion->ref_count, 1);
|
atomic_add(®ion->ref_count, 1);
|
||||||
|
|
||||||
release_sem_etc(region_hash_sem, READ_COUNT, 0);
|
release_sem_etc(region_hash_sem, READ_COUNT, 0);
|
||||||
|
|
||||||
return region;
|
return region;
|
||||||
@@ -507,7 +506,8 @@ map_backing_store(vm_address_space *aspace, vm_store *store, void **_virtualAddr
|
|||||||
off_t old_store_commitment = store->committed_size; // Note what we had
|
off_t old_store_commitment = store->committed_size; // Note what we had
|
||||||
off_t commitment = (store->ops->commit)(store, offset + size); // Commit through to the new end
|
off_t commitment = (store->ops->commit)(store, offset + size); // Commit through to the new end
|
||||||
if (commitment < offset + size) { // Uh oh - didn't work
|
if (commitment < offset + size) { // Uh oh - didn't work
|
||||||
if (cache->temporary) { // If this is a temporary cache, Check to see if we ran out of space and return error.
|
if (cache->temporary) {
|
||||||
|
// If this is a temporary cache, Check to see if we ran out of space and return error.
|
||||||
int state = disable_interrupts();
|
int state = disable_interrupts();
|
||||||
acquire_spinlock(&max_commit_lock);
|
acquire_spinlock(&max_commit_lock);
|
||||||
|
|
||||||
@@ -1597,48 +1597,6 @@ vm_delete_areas(struct vm_address_space *aspace)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
vm_resize_region(aspace_id aid, region_id rid, size_t newSize)
|
|
||||||
{
|
|
||||||
// ToDo: this is broken!
|
|
||||||
vm_cache_ref *myCacheRef;
|
|
||||||
vm_region *myRegion,*current;
|
|
||||||
size_t oldSize;
|
|
||||||
bool failed = false;
|
|
||||||
|
|
||||||
// Steps:
|
|
||||||
//1) Get the vm_cache_ref for the region
|
|
||||||
|
|
||||||
myRegion = vm_get_region_by_id(rid);
|
|
||||||
if (!myRegion)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
myCacheRef = myRegion->cache_ref;
|
|
||||||
|
|
||||||
// 2) Resize all of the regions from the vm_cache_ref (fix them all and fail if they can't be resized)
|
|
||||||
|
|
||||||
oldSize = myRegion->size;
|
|
||||||
for (current = myCacheRef->region_list;current;current = current->cache_next) {
|
|
||||||
if (current->aspace_next->base <= (current->base + newSize)) {
|
|
||||||
failed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current->size = newSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (failed) { // OH NO! Go back and fix all of the broken ones...
|
|
||||||
for (current = myCacheRef->region_list;current;current = current->cache_next)
|
|
||||||
current->size = oldSize;
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) Update the vm_cache size
|
|
||||||
|
|
||||||
myCacheRef->cache->virtual_size = newSize;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
vm_thread_dump_max_commit(void *unused)
|
vm_thread_dump_max_commit(void *unused)
|
||||||
{
|
{
|
||||||
@@ -2455,9 +2413,68 @@ set_area_protection(area_id area, uint32 newProtection)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
resize_area(area_id area, size_t newSize)
|
resize_area(area_id areaID, size_t newSize)
|
||||||
{
|
{
|
||||||
// ToDo: implement resize_area()
|
vm_cache_ref *cache;
|
||||||
|
vm_region *area, *current;
|
||||||
|
size_t oldSize;
|
||||||
|
bool failed = false;
|
||||||
|
|
||||||
|
// is newSize a multiple of B_PAGE_SIZE?
|
||||||
|
if (newSize & (B_PAGE_SIZE - 1))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
area = vm_get_region_by_id(areaID);
|
||||||
|
if (area == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// Resize all areas of this area's cache
|
||||||
|
|
||||||
|
cache = area->cache_ref;
|
||||||
|
oldSize = area->size;
|
||||||
|
|
||||||
|
// ToDo: we should only allow to resize anonymous memory areas!
|
||||||
|
if (!cache->cache->temporary)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
|
if (oldSize < newSize) {
|
||||||
|
// We need to check if all areas of this cache can be resized
|
||||||
|
|
||||||
|
for (current = cache->region_list; current; current = current->cache_next) {
|
||||||
|
if (current->aspace_next && current->aspace_next->base <= (current->base + newSize))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay, looks good so far, so let's do it
|
||||||
|
|
||||||
|
for (current = cache->region_list; current; current = current->cache_next) {
|
||||||
|
if (current->aspace_next && current->aspace_next->base <= (current->base + newSize)) {
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
current->size = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
// This shouldn't really be possible, but hey, who knows
|
||||||
|
for (current = cache->region_list; current; current = current->cache_next)
|
||||||
|
current->size = oldSize;
|
||||||
|
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_cache_resize(cache, newSize);
|
||||||
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
|
// ToDo: we must honour the lock restrictions of this region
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
err:
|
||||||
|
mutex_unlock(&cache->lock);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2590,8 +2607,7 @@ _user_set_area_protection(area_id area, uint32 newProtection)
|
|||||||
status_t
|
status_t
|
||||||
_user_resize_area(area_id area, size_t newSize)
|
_user_resize_area(area_id area, size_t newSize)
|
||||||
{
|
{
|
||||||
// ToDo: implement resize_area()
|
return resize_area(area, newSize);
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user