From eb445177f99911dab2824c1a806e192f0838255f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 20 Dec 2006 12:30:07 +0000 Subject: [PATCH] * When a vm_cache is merged with another one, we now remove the consumer; that allows for an extra check in vm_cache_release_ref() as the cache shouldn't have any areas or consumers at this point. * Fixed a locking problem in vm_cache_remove_consumer(): the cache was acquired after its lock was gone, so someone else might have released in the mean time. * if the cache's source is to be replaced, we now no longer release its lock after having merged it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19570 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/vm/vm_cache.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/system/kernel/vm/vm_cache.c b/src/system/kernel/vm/vm_cache.c index 66eb26d274..833a2ae59a 100644 --- a/src/system/kernel/vm/vm_cache.c +++ b/src/system/kernel/vm/vm_cache.c @@ -183,6 +183,11 @@ vm_cache_release_ref(vm_cache_ref *cacheRef) // delete this cache + if (cacheRef->areas != NULL) + panic("cache to be deleted still has areas"); + if (!list_is_empty(&cacheRef->cache->consumers)) + panic("cache %p to be deleted still has consumers", cacheRef->cache); + // delete the cache's backing store cacheRef->cache->store->ops->destroy(cacheRef->cache->store); @@ -415,7 +420,7 @@ vm_cache_remove_consumer(vm_cache_ref *cacheRef, vm_cache *consumer) vm_cache_ref *consumerRef; vm_page *page, *nextPage; - consumer = list_get_first_item(&cache->consumers); + consumer = list_remove_head_item(&cache->consumers); consumerRef = consumer->ref; mutex_lock(&consumerRef->lock); @@ -445,12 +450,8 @@ vm_cache_remove_consumer(vm_cache_ref *cacheRef, vm_cache *consumer) mutex_unlock(&consumerRef->lock); } - mutex_unlock(&cacheRef->lock); - if (newSource != NULL) { // The remaining consumer has gotten a new source - mutex_lock(&cacheRef->lock); - list_remove_item(&newSource->consumers, cache); list_add_item(&newSource->consumers, consumer); consumer->source = newSource; @@ -461,7 +462,8 @@ vm_cache_remove_consumer(vm_cache_ref *cacheRef, vm_cache *consumer) // Release the other reference to the cache - we take over // its reference of its source cache vm_cache_release_ref(cacheRef); - } + } else + mutex_unlock(&cacheRef->lock); vm_cache_release_ref(cacheRef); } @@ -481,9 +483,9 @@ vm_cache_add_consumer(vm_cache_ref *cacheRef, vm_cache *consumer) consumer->source = cacheRef->cache; list_add_item(&cacheRef->cache->consumers, consumer); - mutex_unlock(&cacheRef->lock); - vm_cache_acquire_ref(cacheRef); + + mutex_unlock(&cacheRef->lock); }