Replaced the vm_cache mutex by a cutex. This should save quite a few
semaphores. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25277 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8562499f44
commit
184de764fe
|
@ -135,7 +135,7 @@ struct vm_dummy_page : vm_page {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vm_cache {
|
struct vm_cache {
|
||||||
mutex lock;
|
cutex lock;
|
||||||
struct vm_area *areas;
|
struct vm_area *areas;
|
||||||
vint32 ref_count;
|
vint32 ref_count;
|
||||||
struct list_link consumer_link;
|
struct list_link consumer_link;
|
||||||
|
|
|
@ -119,7 +119,7 @@ reserve_pages(file_cache_ref *ref, size_t reservePages, bool isWrite)
|
||||||
{
|
{
|
||||||
if (vm_low_memory_state() != B_NO_LOW_MEMORY) {
|
if (vm_low_memory_state() != B_NO_LOW_MEMORY) {
|
||||||
vm_cache *cache = ref->cache;
|
vm_cache *cache = ref->cache;
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (list_is_empty(&cache->consumers) && cache->areas == NULL
|
if (list_is_empty(&cache->consumers) && cache->areas == NULL
|
||||||
&& access_is_sequential(ref)) {
|
&& access_is_sequential(ref)) {
|
||||||
|
@ -153,7 +153,7 @@ reserve_pages(file_cache_ref *ref, size_t reservePages, bool isWrite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_page_reserve_pages(reservePages);
|
vm_page_reserve_pages(reservePages);
|
||||||
|
@ -208,7 +208,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, false);
|
push_access(ref, offset, bufferSize, false);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
// read file into reserved pages
|
// read file into reserved pages
|
||||||
|
@ -229,7 +229,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
for (int32 i = 0; i < pageIndex; i++) {
|
for (int32 i = 0; i < pageIndex; i++) {
|
||||||
busyConditions[i].Unpublish();
|
busyConditions[i].Unpublish();
|
||||||
|
@ -263,7 +263,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve_pages(ref, reservePages, false);
|
reserve_pages(ref, reservePages, false);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
// make the pages accessible in the cache
|
// make the pages accessible in the cache
|
||||||
for (int32 i = pageIndex; i-- > 0;) {
|
for (int32 i = pageIndex; i-- > 0;) {
|
||||||
|
@ -292,7 +292,7 @@ read_from_file(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
vec.iov_len = bufferSize;
|
vec.iov_len = bufferSize;
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, false);
|
push_access(ref, offset, bufferSize, false);
|
||||||
mutex_unlock(&ref->cache->lock);
|
cutex_unlock(&ref->cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
status_t status = vfs_read_pages(ref->vnode, cookie, offset + pageOffset,
|
status_t status = vfs_read_pages(ref->vnode, cookie, offset + pageOffset,
|
||||||
|
@ -300,7 +300,7 @@ read_from_file(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
reserve_pages(ref, reservePages, false);
|
reserve_pages(ref, reservePages, false);
|
||||||
|
|
||||||
mutex_lock(&ref->cache->lock);
|
cutex_lock(&ref->cache->lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ write_to_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, true);
|
push_access(ref, offset, bufferSize, true);
|
||||||
mutex_unlock(&ref->cache->lock);
|
cutex_unlock(&ref->cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
// copy contents (and read in partially written pages first)
|
// copy contents (and read in partially written pages first)
|
||||||
|
@ -433,7 +433,7 @@ write_to_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
reserve_pages(ref, reservePages, true);
|
reserve_pages(ref, reservePages, true);
|
||||||
|
|
||||||
mutex_lock(&ref->cache->lock);
|
cutex_lock(&ref->cache->lock);
|
||||||
|
|
||||||
// unmap the pages again
|
// unmap the pages again
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ write_to_file(file_cache_ref *ref, void *cookie, off_t offset, int32 pageOffset,
|
||||||
vec.iov_len = bufferSize;
|
vec.iov_len = bufferSize;
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, true);
|
push_access(ref, offset, bufferSize, true);
|
||||||
mutex_unlock(&ref->cache->lock);
|
cutex_unlock(&ref->cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
|
@ -508,7 +508,7 @@ write_to_file(file_cache_ref *ref, void *cookie, off_t offset, int32 pageOffset,
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
reserve_pages(ref, reservePages, true);
|
reserve_pages(ref, reservePages, true);
|
||||||
|
|
||||||
mutex_lock(&ref->cache->lock);
|
cutex_lock(&ref->cache->lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,7 @@ cache_io(void *_cacheRef, void *cookie, off_t offset, addr_t buffer,
|
||||||
size_t reservePages = 0;
|
size_t reservePages = 0;
|
||||||
|
|
||||||
reserve_pages(ref, lastReservedPages, doWrite);
|
reserve_pages(ref, lastReservedPages, doWrite);
|
||||||
MutexLocker locker(cache->lock);
|
CutexLocker locker(cache->lock);
|
||||||
|
|
||||||
while (bytesLeft > 0) {
|
while (bytesLeft > 0) {
|
||||||
// check if this page is already in memory
|
// check if this page is already in memory
|
||||||
|
@ -780,7 +780,7 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
||||||
off_t lastOffset = offset;
|
off_t lastOffset = offset;
|
||||||
size_t lastSize = 0;
|
size_t lastSize = 0;
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
for (; bytesLeft > 0; offset += B_PAGE_SIZE) {
|
for (; bytesLeft > 0; offset += B_PAGE_SIZE) {
|
||||||
// check if this page is already in memory
|
// check if this page is already in memory
|
||||||
|
@ -792,9 +792,9 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
||||||
// if busy retry again later
|
// if busy retry again later
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
@ -825,7 +825,7 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
||||||
read_into_cache(ref, lastOffset, lastLeft, NULL, 0);
|
read_into_cache(ref, lastOffset, lastLeft, NULL, 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -985,7 +985,7 @@ file_cache_set_size(void *_cacheRef, off_t newSize)
|
||||||
if (ref == NULL)
|
if (ref == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
MutexLocker _(ref->cache->lock);
|
CutexLocker _(ref->cache->lock);
|
||||||
|
|
||||||
off_t offset = ref->cache->virtual_size;
|
off_t offset = ref->cache->virtual_size;
|
||||||
off_t size = newSize;
|
off_t size = newSize;
|
||||||
|
|
|
@ -1236,7 +1236,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache,
|
||||||
TRACE(("map_backing_store: aspace %p, cache %p, *vaddr %p, offset 0x%Lx, size %lu, addressSpec %ld, wiring %d, protection %d, _area %p, area_name '%s'\n",
|
TRACE(("map_backing_store: aspace %p, cache %p, *vaddr %p, offset 0x%Lx, size %lu, addressSpec %ld, wiring %d, protection %d, _area %p, area_name '%s'\n",
|
||||||
addressSpace, cache, *_virtualAddress, offset, size, addressSpec,
|
addressSpace, cache, *_virtualAddress, offset, size, addressSpec,
|
||||||
wiring, protection, _area, areaName));
|
wiring, protection, _area, areaName));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
vm_area *area = create_area_struct(addressSpace, areaName, wiring,
|
vm_area *area = create_area_struct(addressSpace, areaName, wiring,
|
||||||
protection);
|
protection);
|
||||||
|
@ -1267,7 +1267,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache,
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&newCache->lock);
|
cutex_lock(&newCache->lock);
|
||||||
newCache->type = CACHE_TYPE_RAM;
|
newCache->type = CACHE_TYPE_RAM;
|
||||||
newCache->temporary = 1;
|
newCache->temporary = 1;
|
||||||
newCache->scan_skip = cache->scan_skip;
|
newCache->scan_skip = cache->scan_skip;
|
||||||
|
@ -1310,7 +1310,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache,
|
||||||
// point the cache back to the area
|
// point the cache back to the area
|
||||||
vm_cache_insert_area_locked(cache, area);
|
vm_cache_insert_area_locked(cache, area);
|
||||||
if (mapping == REGION_PRIVATE_MAP)
|
if (mapping == REGION_PRIVATE_MAP)
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
// insert the area in the global area hash table
|
// insert the area in the global area hash table
|
||||||
acquire_sem_etc(sAreaHashLock, WRITE_COUNT, 0 ,0);
|
acquire_sem_etc(sAreaHashLock, WRITE_COUNT, 0 ,0);
|
||||||
|
@ -1328,10 +1328,10 @@ err2:
|
||||||
// We created this cache, so we must delete it again. Note, that we
|
// We created this cache, so we must delete it again. Note, that we
|
||||||
// need to temporarily unlock the source cache or we'll otherwise
|
// need to temporarily unlock the source cache or we'll otherwise
|
||||||
// deadlock, since vm_cache_remove_consumer will try to lock it too.
|
// deadlock, since vm_cache_remove_consumer will try to lock it too.
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
mutex_unlock(&sourceCache->lock);
|
cutex_unlock(&sourceCache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
mutex_lock(&sourceCache->lock);
|
cutex_lock(&sourceCache->lock);
|
||||||
}
|
}
|
||||||
err1:
|
err1:
|
||||||
free(area->name);
|
free(area->name);
|
||||||
|
@ -1525,13 +1525,13 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
status = map_backing_store(addressSpace, cache, address, 0, size,
|
status = map_backing_store(addressSpace, cache, address, 0, size,
|
||||||
addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name,
|
addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name,
|
||||||
unmapAddressRange);
|
unmapAddressRange);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
@ -1554,7 +1554,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
vm_page_reserve_pages(reservePages);
|
vm_page_reserve_pages(reservePages);
|
||||||
|
|
||||||
// Allocate and map all pages for this area
|
// Allocate and map all pages for this area
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
for (addr_t address = area->base; address < area->base + (area->size - 1);
|
for (addr_t address = area->base; address < area->base + (area->size - 1);
|
||||||
|
@ -1579,7 +1579,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
vm_map_page(area, page, address, protection);
|
vm_map_page(area, page, address, protection);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_page_unreserve_pages(reservePages);
|
vm_page_unreserve_pages(reservePages);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1595,7 +1595,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
if (!kernel_startup)
|
if (!kernel_startup)
|
||||||
panic("ALREADY_WIRED flag used outside kernel startup\n");
|
panic("ALREADY_WIRED flag used outside kernel startup\n");
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
map->ops->lock(map);
|
map->ops->lock(map);
|
||||||
|
|
||||||
for (addr_t virtualAddress = area->base; virtualAddress < area->base
|
for (addr_t virtualAddress = area->base; virtualAddress < area->base
|
||||||
|
@ -1622,7 +1622,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
}
|
}
|
||||||
|
|
||||||
map->ops->unlock(map);
|
map->ops->unlock(map);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1638,7 +1638,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
|
|
||||||
vm_page_reserve_pages(reservePages);
|
vm_page_reserve_pages(reservePages);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
map->ops->lock(map);
|
map->ops->lock(map);
|
||||||
|
|
||||||
for (virtualAddress = area->base; virtualAddress < area->base
|
for (virtualAddress = area->base; virtualAddress < area->base
|
||||||
|
@ -1660,7 +1660,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
||||||
}
|
}
|
||||||
|
|
||||||
map->ops->unlock(map);
|
map->ops->unlock(map);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_page_unreserve_pages(reservePages);
|
vm_page_unreserve_pages(reservePages);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1739,13 +1739,13 @@ vm_map_physical_memory(team_id team, const char *name, void **_address,
|
||||||
cache->type = CACHE_TYPE_DEVICE;
|
cache->type = CACHE_TYPE_DEVICE;
|
||||||
cache->virtual_size = size;
|
cache->virtual_size = size;
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
status_t status = map_backing_store(locker.AddressSpace(), cache, _address,
|
status_t status = map_backing_store(locker.AddressSpace(), cache, _address,
|
||||||
0, size, addressSpec & ~B_MTR_MASK, B_FULL_LOCK, protection,
|
0, size, addressSpec & ~B_MTR_MASK, B_FULL_LOCK, protection,
|
||||||
REGION_NO_PRIVATE_MAP, &area, name, false);
|
REGION_NO_PRIVATE_MAP, &area, name, false);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
@ -1821,13 +1821,13 @@ vm_create_null_area(team_id team, const char *name, void **address,
|
||||||
cache->type = CACHE_TYPE_NULL;
|
cache->type = CACHE_TYPE_NULL;
|
||||||
cache->virtual_size = size;
|
cache->virtual_size = size;
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
status = map_backing_store(locker.AddressSpace(), cache, address, 0, size,
|
status = map_backing_store(locker.AddressSpace(), cache, address, 0, size,
|
||||||
addressSpec, 0, B_KERNEL_READ_AREA, REGION_NO_PRIVATE_MAP, &area, name,
|
addressSpec, 0, B_KERNEL_READ_AREA, REGION_NO_PRIVATE_MAP, &area, name,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
@ -1929,14 +1929,14 @@ _vm_map_file(team_id team, const char *name, void **_address, uint32 addressSpec
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
vm_area *area;
|
vm_area *area;
|
||||||
status = map_backing_store(locker.AddressSpace(), cache, _address,
|
status = map_backing_store(locker.AddressSpace(), cache, _address,
|
||||||
offset, size, addressSpec, 0, protection, mapping, &area, name,
|
offset, size, addressSpec, 0, protection, mapping, &area, name,
|
||||||
addressSpec == B_EXACT_ADDRESS);
|
addressSpec == B_EXACT_ADDRESS);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK || mapping == REGION_PRIVATE_MAP) {
|
if (status < B_OK || mapping == REGION_PRIVATE_MAP) {
|
||||||
// map_backing_store() cannot know we no longer need the ref
|
// map_backing_store() cannot know we no longer need the ref
|
||||||
|
@ -1971,14 +1971,14 @@ vm_area_get_locked_cache(vm_area *area)
|
||||||
vm_cache_acquire_ref(cache);
|
vm_cache_acquire_ref(cache);
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
locker.Lock();
|
locker.Lock();
|
||||||
if (cache == area->cache)
|
if (cache == area->cache)
|
||||||
return cache;
|
return cache;
|
||||||
|
|
||||||
// the cache changed in the meantime
|
// the cache changed in the meantime
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1987,7 +1987,7 @@ vm_area_get_locked_cache(vm_area *area)
|
||||||
void
|
void
|
||||||
vm_area_put_locked_cache(vm_cache *cache)
|
vm_area_put_locked_cache(vm_cache *cache)
|
||||||
{
|
{
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2207,7 +2207,7 @@ vm_copy_on_write_area(vm_cache* lowerCache)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&upperCache->lock);
|
cutex_lock(&upperCache->lock);
|
||||||
|
|
||||||
upperCache->type = CACHE_TYPE_RAM;
|
upperCache->type = CACHE_TYPE_RAM;
|
||||||
upperCache->temporary = 1;
|
upperCache->temporary = 1;
|
||||||
|
@ -3040,8 +3040,10 @@ dump_cache(int argc, char **argv)
|
||||||
kprintf(" virtual_size: 0x%Lx\n", cache->virtual_size);
|
kprintf(" virtual_size: 0x%Lx\n", cache->virtual_size);
|
||||||
kprintf(" temporary: %ld\n", cache->temporary);
|
kprintf(" temporary: %ld\n", cache->temporary);
|
||||||
kprintf(" scan_skip: %ld\n", cache->scan_skip);
|
kprintf(" scan_skip: %ld\n", cache->scan_skip);
|
||||||
|
kprintf(" lock: %p\n", &cache->lock);
|
||||||
|
#ifdef KDEBUG
|
||||||
kprintf(" lock.holder: %ld\n", cache->lock.holder);
|
kprintf(" lock.holder: %ld\n", cache->lock.holder);
|
||||||
kprintf(" lock.sem: 0x%lx\n", cache->lock.sem);
|
#endif
|
||||||
kprintf(" areas:\n");
|
kprintf(" areas:\n");
|
||||||
|
|
||||||
for (vm_area *area = cache->areas; area != NULL; area = area->cache_next) {
|
for (vm_area *area = cache->areas; area != NULL; area = area->cache_next) {
|
||||||
|
@ -3689,15 +3691,6 @@ vm_init_post_sem(kernel_args *args)
|
||||||
arch_vm_translation_map_init_post_sem(args);
|
arch_vm_translation_map_init_post_sem(args);
|
||||||
vm_address_space_init_post_sem();
|
vm_address_space_init_post_sem();
|
||||||
|
|
||||||
for (area = vm_kernel_address_space()->areas; area;
|
|
||||||
area = area->address_space_next) {
|
|
||||||
if (area->id == RESERVED_AREA_ID)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (area->cache->lock.sem < 0)
|
|
||||||
mutex_init(&area->cache->lock, "vm_cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
sAreaHashLock = create_sem(WRITE_COUNT, "area hash");
|
sAreaHashLock = create_sem(WRITE_COUNT, "area hash");
|
||||||
mutex_init(&sAreaCacheLock, "area->cache");
|
mutex_init(&sAreaCacheLock, "area->cache");
|
||||||
mutex_init(&sMappingLock, "page mappings");
|
mutex_init(&sMappingLock, "page mappings");
|
||||||
|
@ -3859,10 +3852,10 @@ retry:
|
||||||
|
|
||||||
vm_cache_acquire_ref(source);
|
vm_cache_acquire_ref(source);
|
||||||
|
|
||||||
mutex_lock(&source->lock);
|
cutex_lock(&source->lock);
|
||||||
|
|
||||||
if (source->busy) {
|
if (source->busy) {
|
||||||
mutex_unlock(&source->lock);
|
cutex_unlock(&source->lock);
|
||||||
vm_cache_release_ref(source);
|
vm_cache_release_ref(source);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
@ -3896,7 +3889,7 @@ fault_remove_dummy_page(vm_dummy_page &dummyPage, bool isLocked)
|
||||||
{
|
{
|
||||||
vm_cache *cache = dummyPage.cache;
|
vm_cache *cache = dummyPage.cache;
|
||||||
if (!isLocked)
|
if (!isLocked)
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (dummyPage.state == PAGE_STATE_BUSY) {
|
if (dummyPage.state == PAGE_STATE_BUSY) {
|
||||||
vm_cache_remove_page(cache, &dummyPage);
|
vm_cache_remove_page(cache, &dummyPage);
|
||||||
|
@ -3905,7 +3898,7 @@ fault_remove_dummy_page(vm_dummy_page &dummyPage, bool isLocked)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isLocked)
|
if (!isLocked)
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
|
@ -3930,7 +3923,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
vm_page *page = NULL;
|
vm_page *page = NULL;
|
||||||
|
|
||||||
vm_cache_acquire_ref(cache);
|
vm_cache_acquire_ref(cache);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
// we release this later in the loop
|
// we release this later in the loop
|
||||||
|
|
||||||
while (cache != NULL) {
|
while (cache != NULL) {
|
||||||
|
@ -3954,9 +3947,9 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
{
|
{
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
|
@ -3965,7 +3958,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
// the top cache.
|
// the top cache.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(cache);
|
entry.Add(cache);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
|
@ -3989,7 +3982,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
ConditionVariable busyCondition;
|
ConditionVariable busyCondition;
|
||||||
busyCondition.Publish(page, "page");
|
busyCondition.Publish(page, "page");
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
// get a virtual address for the page
|
// get a virtual address for the page
|
||||||
iovec vec;
|
iovec vec;
|
||||||
|
@ -4004,7 +3997,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
|
|
||||||
map->ops->put_physical_page((addr_t)vec.iov_base);
|
map->ops->put_physical_page((addr_t)vec.iov_base);
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
// on error remove and free the page
|
// on error remove and free the page
|
||||||
|
@ -4015,7 +4008,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
vm_cache_remove_page(cache, page);
|
vm_cache_remove_page(cache, page);
|
||||||
vm_page_set_state(page, PAGE_STATE_FREE);
|
vm_page_set_state(page, PAGE_STATE_FREE);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -4038,16 +4031,16 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
// the source cache is currently in the process of being merged
|
// the source cache is currently in the process of being merged
|
||||||
// with his only consumer (cacheRef); since its pages are moved
|
// with his only consumer (cacheRef); since its pages are moved
|
||||||
// upwards, too, we try this cache again
|
// upwards, too, we try this cache again
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
thread_yield(true);
|
thread_yield(true);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
// The cache became busy, which means, it is about to be
|
// The cache became busy, which means, it is about to be
|
||||||
// removed by vm_cache_remove_consumer(). We start again with
|
// removed by vm_cache_remove_consumer(). We start again with
|
||||||
// the top cache.
|
// the top cache.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(cache);
|
entry.Add(cache);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
|
@ -4058,7 +4051,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
} else if (status < B_OK)
|
} else if (status < B_OK)
|
||||||
nextCache = NULL;
|
nextCache = NULL;
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
// at this point, we still hold a ref to this cache (through lastCacheRef)
|
// at this point, we still hold a ref to this cache (through lastCacheRef)
|
||||||
|
|
||||||
cache = nextCache;
|
cache = nextCache;
|
||||||
|
@ -4073,7 +4066,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
// Read-only pages come in the deepest cache - only the
|
// Read-only pages come in the deepest cache - only the
|
||||||
// top most cache may have direct write access.
|
// top most cache may have direct write access.
|
||||||
vm_cache_acquire_ref(cache);
|
vm_cache_acquire_ref(cache);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
// The cache became busy, which means, it is about to be
|
// The cache became busy, which means, it is about to be
|
||||||
|
@ -4081,7 +4074,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
// the top cache.
|
// the top cache.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(cache);
|
entry.Add(cache);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
|
@ -4092,7 +4085,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||||
// for, but it could as well be a dummy page from someone
|
// for, but it could as well be a dummy page from someone
|
||||||
// else or an otherwise busy page. We can't really handle
|
// else or an otherwise busy page. We can't really handle
|
||||||
// that here. Hence we completely restart this functions.
|
// that here. Hence we completely restart this functions.
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
}
|
}
|
||||||
|
@ -4135,7 +4128,7 @@ fault_get_page(vm_translation_map *map, vm_cache *topCache, off_t cacheOffset,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Remove the dummy page, if it has been inserted.
|
// Remove the dummy page, if it has been inserted.
|
||||||
mutex_lock(&topCache->lock);
|
cutex_lock(&topCache->lock);
|
||||||
|
|
||||||
if (dummyPage.state == PAGE_STATE_BUSY) {
|
if (dummyPage.state == PAGE_STATE_BUSY) {
|
||||||
ASSERT_PRINT(dummyPage.cache == topCache, "dummy page: %p\n",
|
ASSERT_PRINT(dummyPage.cache == topCache, "dummy page: %p\n",
|
||||||
|
@ -4143,7 +4136,7 @@ fault_get_page(vm_translation_map *map, vm_cache *topCache, off_t cacheOffset,
|
||||||
fault_remove_dummy_page(dummyPage, true);
|
fault_remove_dummy_page(dummyPage, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&topCache->lock);
|
cutex_unlock(&topCache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
|
@ -4182,9 +4175,9 @@ fault_get_page(vm_translation_map *map, vm_cache *topCache, off_t cacheOffset,
|
||||||
// This is not the top cache into which we inserted the dummy page,
|
// This is not the top cache into which we inserted the dummy page,
|
||||||
// let's remove it from there. We need to temporarily unlock our
|
// let's remove it from there. We need to temporarily unlock our
|
||||||
// cache to comply with the cache locking policy.
|
// cache to comply with the cache locking policy.
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
fault_remove_dummy_page(dummyPage, false);
|
fault_remove_dummy_page(dummyPage, false);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4232,8 +4225,8 @@ if (cacheOffset == 0x12000)
|
||||||
if (sourcePage->state != PAGE_STATE_MODIFIED)
|
if (sourcePage->state != PAGE_STATE_MODIFIED)
|
||||||
vm_page_set_state(sourcePage, PAGE_STATE_ACTIVE);
|
vm_page_set_state(sourcePage, PAGE_STATE_ACTIVE);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
mutex_lock(&topCache->lock);
|
cutex_lock(&topCache->lock);
|
||||||
|
|
||||||
// Since the top cache has been unlocked for a while, someone else
|
// Since the top cache has been unlocked for a while, someone else
|
||||||
// (vm_cache_remove_consumer()) might have replaced our dummy page.
|
// (vm_cache_remove_consumer()) might have replaced our dummy page.
|
||||||
|
@ -4251,9 +4244,9 @@ if (cacheOffset == 0x12000)
|
||||||
// The page is busy, wait till it becomes unbusy.
|
// The page is busy, wait till it becomes unbusy.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(newPage);
|
entry.Add(newPage);
|
||||||
mutex_unlock(&topCache->lock);
|
cutex_unlock(&topCache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
mutex_lock(&topCache->lock);
|
cutex_lock(&topCache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newPage) {
|
if (newPage) {
|
||||||
|
@ -4365,7 +4358,7 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&topCache->lock);
|
cutex_unlock(&topCache->lock);
|
||||||
|
|
||||||
// The top most cache has no fault handler, so let's see if the cache or its sources
|
// The top most cache has no fault handler, so let's see if the cache or its sources
|
||||||
// already have the page we're searching for (we're going from top to bottom)
|
// already have the page we're searching for (we're going from top to bottom)
|
||||||
|
@ -4415,7 +4408,7 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser)
|
||||||
|
|
||||||
vm_map_page(area, page, address, newProtection);
|
vm_map_page(area, page, address, newProtection);
|
||||||
|
|
||||||
mutex_unlock(&pageSource->lock);
|
cutex_unlock(&pageSource->lock);
|
||||||
vm_cache_release_ref(pageSource);
|
vm_cache_release_ref(pageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ delete_cache(vm_cache* cache)
|
||||||
if (cache->source)
|
if (cache->source)
|
||||||
vm_cache_remove_consumer(cache->source, cache);
|
vm_cache_remove_consumer(cache->source, cache);
|
||||||
|
|
||||||
mutex_destroy(&cache->lock);
|
cutex_destroy(&cache->lock);
|
||||||
free(cache);
|
free(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,14 +194,7 @@ vm_cache_create(vm_store* store)
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
status_t status = mutex_init(&cache->lock, "vm_cache");
|
cutex_init(&cache->lock, "vm_cache");
|
||||||
if (status < B_OK && (!kernel_startup || status != B_NO_MORE_SEMS)) {
|
|
||||||
// During early boot, we cannot create semaphores - they are
|
|
||||||
// created later in vm_init_post_sem()
|
|
||||||
free(cache);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_init_etc(&cache->consumers, offsetof(vm_cache, consumer_link));
|
list_init_etc(&cache->consumers, offsetof(vm_cache, consumer_link));
|
||||||
cache->page_list = NULL;
|
cache->page_list = NULL;
|
||||||
cache->areas = NULL;
|
cache->areas = NULL;
|
||||||
|
@ -272,7 +265,7 @@ vm_cache_release_ref(vm_cache* cache)
|
||||||
vm_cache* c;
|
vm_cache* c;
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
if (cacheRef->lock.holder != find_thread(NULL)) {
|
if (cacheRef->lock.holder != find_thread(NULL)) {
|
||||||
mutex_lock(&cacheRef->lock);
|
cutex_lock(&cacheRef->lock);
|
||||||
locked = true;
|
locked = true;
|
||||||
}
|
}
|
||||||
for (a = cacheRef->areas; a != NULL; a = a->cache_next)
|
for (a = cacheRef->areas; a != NULL; a = a->cache_next)
|
||||||
|
@ -285,7 +278,7 @@ vm_cache_release_ref(vm_cache* cache)
|
||||||
if (cacheRef->ref_count < min)
|
if (cacheRef->ref_count < min)
|
||||||
panic("cache_ref %p has too little ref_count!!!!", cacheRef);
|
panic("cache_ref %p has too little ref_count!!!!", cacheRef);
|
||||||
if (locked)
|
if (locked)
|
||||||
mutex_unlock(&cacheRef->lock);
|
cutex_unlock(&cacheRef->lock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
@ -317,7 +310,7 @@ vm_cache_acquire_page_cache_ref(vm_page* page)
|
||||||
vm_page*
|
vm_page*
|
||||||
vm_cache_lookup_page(vm_cache* cache, off_t offset)
|
vm_cache_lookup_page(vm_cache* cache, off_t offset)
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
struct page_lookup_key key;
|
struct page_lookup_key key;
|
||||||
key.offset = (uint32)(offset >> PAGE_SHIFT);
|
key.offset = (uint32)(offset >> PAGE_SHIFT);
|
||||||
|
@ -343,7 +336,7 @@ vm_cache_insert_page(vm_cache* cache, vm_page* page, off_t offset)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_insert_page: cache %p, page %p, offset %Ld\n",
|
TRACE(("vm_cache_insert_page: cache %p, page %p, offset %Ld\n",
|
||||||
cache, page, offset));
|
cache, page, offset));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
if (page->cache != NULL) {
|
if (page->cache != NULL) {
|
||||||
panic("insert page %p into cache %p: page cache is set to %p\n",
|
panic("insert page %p into cache %p: page cache is set to %p\n",
|
||||||
|
@ -390,7 +383,7 @@ void
|
||||||
vm_cache_remove_page(vm_cache* cache, vm_page* page)
|
vm_cache_remove_page(vm_cache* cache, vm_page* page)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_remove_page: cache %p, page %p\n", cache, page));
|
TRACE(("vm_cache_remove_page: cache %p, page %p\n", cache, page));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
if (page->cache != cache) {
|
if (page->cache != cache) {
|
||||||
panic("remove page %p from cache %p: page cache is set to %p\n", page,
|
panic("remove page %p from cache %p: page cache is set to %p\n", page,
|
||||||
|
@ -428,9 +421,9 @@ vm_cache_write_modified(vm_cache* cache, bool fsReenter)
|
||||||
if (cache->temporary)
|
if (cache->temporary)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
status_t status = vm_page_write_modified_pages(cache, fsReenter);
|
status_t status = vm_page_write_modified_pages(cache, fsReenter);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +438,7 @@ vm_cache_set_minimal_commitment_locked(vm_cache* cache, off_t commitment)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_set_minimal_commitment_locked(cache %p, commitment %Ld)\n",
|
TRACE(("vm_cache_set_minimal_commitment_locked(cache %p, commitment %Ld)\n",
|
||||||
cache, commitment));
|
cache, commitment));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
vm_store* store = cache->store;
|
vm_store* store = cache->store;
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
|
@ -478,7 +471,7 @@ vm_cache_resize(vm_cache* cache, off_t newSize)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_resize(cache %p, newSize %Ld) old size %Ld\n",
|
TRACE(("vm_cache_resize(cache %p, newSize %Ld) old size %Ld\n",
|
||||||
cache, newSize, cache->virtual_size));
|
cache, newSize, cache->virtual_size));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
status_t status = cache->store->ops->commit(cache->store, newSize);
|
status_t status = cache->store->ops->commit(cache->store, newSize);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
|
@ -509,9 +502,9 @@ vm_cache_resize(vm_cache* cache, off_t newSize)
|
||||||
// wait for page to become unbusy
|
// wait for page to become unbusy
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
// restart from the start of the list
|
// restart from the start of the list
|
||||||
page = cache->page_list;
|
page = cache->page_list;
|
||||||
|
@ -541,7 +534,7 @@ void
|
||||||
vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
||||||
{
|
{
|
||||||
TRACE(("remove consumer vm cache %p from cache %p\n", consumer, cache));
|
TRACE(("remove consumer vm cache %p from cache %p\n", consumer, cache));
|
||||||
ASSERT_LOCKED_MUTEX(&consumer->lock);
|
ASSERT_LOCKED_CUTEX(&consumer->lock);
|
||||||
|
|
||||||
// Remove the store ref before locking the cache. Otherwise we'd call into
|
// Remove the store ref before locking the cache. Otherwise we'd call into
|
||||||
// the VFS while holding the cache lock, which would reverse the usual
|
// the VFS while holding the cache lock, which would reverse the usual
|
||||||
|
@ -550,7 +543,7 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
||||||
cache->store->ops->release_ref(cache->store);
|
cache->store->ops->release_ref(cache->store);
|
||||||
|
|
||||||
// remove the consumer from the cache, but keep its reference until later
|
// remove the consumer from the cache, but keep its reference until later
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
list_remove_item(&cache->consumers, consumer);
|
list_remove_item(&cache->consumers, consumer);
|
||||||
consumer->source = NULL;
|
consumer->source = NULL;
|
||||||
|
|
||||||
|
@ -576,10 +569,10 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
||||||
// need to unlock our cache now
|
// need to unlock our cache now
|
||||||
busyCondition.Publish(cache, "cache");
|
busyCondition.Publish(cache, "cache");
|
||||||
cache->busy = true;
|
cache->busy = true;
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
|
|
||||||
mutex_lock(&consumer->lock);
|
cutex_lock(&consumer->lock);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (cache->areas != NULL || cache->source == NULL
|
if (cache->areas != NULL || cache->source == NULL
|
||||||
|| list_is_empty(&cache->consumers)
|
|| list_is_empty(&cache->consumers)
|
||||||
|
@ -590,7 +583,7 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
||||||
merge = false;
|
merge = false;
|
||||||
cache->busy = false;
|
cache->busy = false;
|
||||||
busyCondition.Unpublish();
|
busyCondition.Unpublish();
|
||||||
mutex_unlock(&consumer->lock);
|
cutex_unlock(&consumer->lock);
|
||||||
vm_cache_release_ref(consumer);
|
vm_cache_release_ref(consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,14 +637,14 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
||||||
vm_cache* newSource = cache->source;
|
vm_cache* newSource = cache->source;
|
||||||
|
|
||||||
// The remaining consumer has gotten a new source
|
// The remaining consumer has gotten a new source
|
||||||
mutex_lock(&newSource->lock);
|
cutex_lock(&newSource->lock);
|
||||||
|
|
||||||
list_remove_item(&newSource->consumers, cache);
|
list_remove_item(&newSource->consumers, cache);
|
||||||
list_add_item(&newSource->consumers, consumer);
|
list_add_item(&newSource->consumers, consumer);
|
||||||
consumer->source = newSource;
|
consumer->source = newSource;
|
||||||
cache->source = NULL;
|
cache->source = NULL;
|
||||||
|
|
||||||
mutex_unlock(&newSource->lock);
|
cutex_unlock(&newSource->lock);
|
||||||
|
|
||||||
// Release the other reference to the cache - we take over
|
// Release the other reference to the cache - we take over
|
||||||
// its reference of its source cache; we can do this here
|
// its reference of its source cache; we can do this here
|
||||||
|
@ -661,7 +654,7 @@ if (cache->ref_count < 2)
|
||||||
panic("cacheRef %p ref count too low!\n", cache);
|
panic("cacheRef %p ref count too low!\n", cache);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
|
||||||
mutex_unlock(&consumer->lock);
|
cutex_unlock(&consumer->lock);
|
||||||
vm_cache_release_ref(consumer);
|
vm_cache_release_ref(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,7 +662,7 @@ panic("cacheRef %p ref count too low!\n", cache);
|
||||||
busyCondition.Unpublish();
|
busyCondition.Unpublish();
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,8 +676,8 @@ void
|
||||||
vm_cache_add_consumer_locked(vm_cache* cache, vm_cache* consumer)
|
vm_cache_add_consumer_locked(vm_cache* cache, vm_cache* consumer)
|
||||||
{
|
{
|
||||||
TRACE(("add consumer vm cache %p to cache %p\n", consumer, cache));
|
TRACE(("add consumer vm cache %p to cache %p\n", consumer, cache));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
ASSERT_LOCKED_MUTEX(&consumer->lock);
|
ASSERT_LOCKED_CUTEX(&consumer->lock);
|
||||||
|
|
||||||
consumer->source = cache;
|
consumer->source = cache;
|
||||||
list_add_item(&cache->consumers, consumer);
|
list_add_item(&cache->consumers, consumer);
|
||||||
|
@ -703,7 +696,7 @@ status_t
|
||||||
vm_cache_insert_area_locked(vm_cache* cache, vm_area* area)
|
vm_cache_insert_area_locked(vm_cache* cache, vm_area* area)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_insert_area_locked(cache %p, area %p)\n", cache, area));
|
TRACE(("vm_cache_insert_area_locked(cache %p, area %p)\n", cache, area));
|
||||||
ASSERT_LOCKED_MUTEX(&cache->lock);
|
ASSERT_LOCKED_CUTEX(&cache->lock);
|
||||||
|
|
||||||
area->cache_next = cache->areas;
|
area->cache_next = cache->areas;
|
||||||
if (area->cache_next)
|
if (area->cache_next)
|
||||||
|
@ -723,7 +716,7 @@ vm_cache_remove_area(vm_cache* cache, vm_area* area)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_remove_area(cache %p, area %p)\n", cache, area));
|
TRACE(("vm_cache_remove_area(cache %p, area %p)\n", cache, area));
|
||||||
|
|
||||||
MutexLocker locker(cache->lock);
|
CutexLocker locker(cache->lock);
|
||||||
|
|
||||||
if (area->cache_prev)
|
if (area->cache_prev)
|
||||||
area->cache_prev->cache_next = area->cache_next;
|
area->cache_prev->cache_next = area->cache_next;
|
||||||
|
|
|
@ -66,15 +66,15 @@ PageCacheLocker::Lock(vm_page* page, bool dontWait)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (dontWait) {
|
if (dontWait) {
|
||||||
if (mutex_trylock(&cache->lock) != B_OK) {
|
if (cutex_trylock(&cache->lock) != B_OK) {
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (cache != page->cache || _IgnorePage(page)) {
|
if (cache != page->cache || _IgnorePage(page)) {
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ PageCacheLocker::Unlock()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vm_cache* cache = fPage->cache;
|
vm_cache* cache = fPage->cache;
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
|
||||||
fPage = NULL;
|
fPage = NULL;
|
||||||
|
|
|
@ -1043,7 +1043,7 @@ page_writer(void* /*unused*/)
|
||||||
|
|
||||||
for (uint32 i = 0; i < numPages; i++) {
|
for (uint32 i = 0; i < numPages; i++) {
|
||||||
vm_cache *cache = u.pages[i]->cache;
|
vm_cache *cache = u.pages[i]->cache;
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (writeStatus[i] == B_OK) {
|
if (writeStatus[i] == B_OK) {
|
||||||
// put it into the active queue
|
// put it into the active queue
|
||||||
|
@ -1069,7 +1069,7 @@ page_writer(void* /*unused*/)
|
||||||
busyConditions[i].Unpublish();
|
busyConditions[i].Unpublish();
|
||||||
|
|
||||||
u.caches[i] = cache;
|
u.caches[i] = cache;
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 i = 0; i < numPages; i++) {
|
for (uint32 i = 0; i < numPages; i++) {
|
||||||
|
@ -1156,12 +1156,10 @@ steal_page(vm_page *page, bool stealActive)
|
||||||
{
|
{
|
||||||
fCache = vm_cache_acquire_page_cache_ref(page);
|
fCache = vm_cache_acquire_page_cache_ref(page);
|
||||||
if (fCache != NULL) {
|
if (fCache != NULL) {
|
||||||
if (fCache->lock.holder != thread_get_current_thread_id()) {
|
if (cutex_trylock(&fCache->lock) != B_OK)
|
||||||
if (mutex_trylock(&fCache->lock) != B_OK)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
fOwnsLock = true;
|
fOwnsLock = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (fCache == page->cache)
|
if (fCache == page->cache)
|
||||||
fIsLocked = true;
|
fIsLocked = true;
|
||||||
|
@ -1171,7 +1169,7 @@ steal_page(vm_page *page, bool stealActive)
|
||||||
~PageCacheTryLocker()
|
~PageCacheTryLocker()
|
||||||
{
|
{
|
||||||
if (fOwnsLock)
|
if (fOwnsLock)
|
||||||
mutex_unlock(&fCache->lock);
|
cutex_unlock(&fCache->lock);
|
||||||
if (fCache != NULL)
|
if (fCache != NULL)
|
||||||
vm_cache_release_ref(fCache);
|
vm_cache_release_ref(fCache);
|
||||||
}
|
}
|
||||||
|
@ -1347,9 +1345,9 @@ vm_page_write_modified_pages(vm_cache *cache, bool fsReenter)
|
||||||
// clear the modified flag
|
// clear the modified flag
|
||||||
vm_clear_map_flags(page, PAGE_MODIFIED);
|
vm_clear_map_flags(page, PAGE_MODIFIED);
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
cutex_unlock(&cache->lock);
|
||||||
status_t status = write_page(page, fsReenter);
|
status_t status = write_page(page, fsReenter);
|
||||||
mutex_lock(&cache->lock);
|
cutex_lock(&cache->lock);
|
||||||
|
|
||||||
InterruptsSpinLocker locker(&sPageLock);
|
InterruptsSpinLocker locker(&sPageLock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue