From 76faade4e77fbdac780d51ba0479fac5bf074e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 10 Sep 2004 23:43:15 +0000 Subject: [PATCH] Cleanup, no functional change. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8910 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/vm/vm_cache.c | 199 ++++++++++++++++++++-------------- 1 file changed, 116 insertions(+), 83 deletions(-) diff --git a/src/kernel/core/vm/vm_cache.c b/src/kernel/core/vm/vm_cache.c index 9020847472..eb3d4d026c 100755 --- a/src/kernel/core/vm/vm_cache.c +++ b/src/kernel/core/vm/vm_cache.c @@ -18,8 +18,17 @@ #include #include +//#define TRACE_VM_CACHE +#ifdef TRACE_VM_CACHE +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + /* hash table of pages keyed by cache they're in and offset */ #define PAGE_TABLE_SIZE 1024 /* make this dynamic */ + static void *page_cache_table; static spinlock page_cache_table_lock; @@ -28,20 +37,21 @@ struct page_lookup_key { vm_cache_ref *ref; }; -static int page_compare_func(void *_p, const void *_key) + +static int +page_compare_func(void *_p, const void *_key) { vm_page *p = _p; const struct page_lookup_key *key = _key; -// dprintf("page_compare_func: p 0x%x, key 0x%x\n", p, key); + TRACE(("page_compare_func: p 0x%x, key 0x%x\n", p, key)); - if(p->cache_ref == key->ref && p->offset == key->offset) + if (p->cache_ref == key->ref && p->offset == key->offset) return 0; - else - return -1; + + return -1; } -#define HASH(offset, ref) ((unsigned int)(offset >> 12) ^ ((unsigned int)(ref)>>4)) static uint32 page_hash_func(void *_p, const void *_key, uint32 range) @@ -54,40 +64,44 @@ page_hash_func(void *_p, const void *_key, uint32 range) else dprintf("page_hash_func: p 0x%x, key 0x%x, HASH = 0x%x\n", p, key, HASH(key->offset, key->ref) % range); #endif - if(p) +#define HASH(offset, ref) ((unsigned int)(offset >> 12) ^ ((unsigned int)(ref)>>4)) + + if (p) return HASH(p->offset, p->cache_ref) % range; - else - return HASH(key->offset, key->ref) % range; + + return HASH(key->offset, key->ref) % range; } -int vm_cache_init(kernel_args *ka) + +int +vm_cache_init(kernel_args *ka) { vm_page p; - page_cache_table = hash_init(PAGE_TABLE_SIZE, - (int)&p.hash_next - (int)&p, - &page_compare_func, - &page_hash_func); - if(!page_cache_table) + page_cache_table = hash_init(PAGE_TABLE_SIZE, (int)&p.hash_next - (int)&p, + &page_compare_func, &page_hash_func); + if (!page_cache_table) panic("vm_cache_init: cannot allocate memory for page cache hash table\n"); page_cache_table_lock = 0; return 0; } -vm_cache *vm_cache_create(vm_store *store) + +vm_cache * +vm_cache_create(vm_store *store) { vm_cache *cache; cache = malloc(sizeof(vm_cache)); - if(cache == NULL) + if (cache == NULL) return NULL; cache->page_list = NULL; cache->ref = NULL; cache->source = NULL; cache->store = store; - if(store != NULL) + if (store != NULL) store->cache = cache; cache->virtual_size = 0; cache->temporary = 0; @@ -96,12 +110,14 @@ vm_cache *vm_cache_create(vm_store *store) return cache; } -vm_cache_ref *vm_cache_ref_create(vm_cache *cache) + +vm_cache_ref * +vm_cache_ref_create(vm_cache *cache) { vm_cache_ref *ref; ref = malloc(sizeof(vm_cache_ref)); - if(ref == NULL) + if (ref == NULL) return NULL; ref->cache = cache; @@ -113,73 +129,82 @@ vm_cache_ref *vm_cache_ref_create(vm_cache *cache) return ref; } -void vm_cache_acquire_ref(vm_cache_ref *cache_ref, bool acquire_store_ref) + +void +vm_cache_acquire_ref(vm_cache_ref *cache_ref, bool acquire_store_ref) { // dprintf("vm_cache_acquire_ref: cache_ref 0x%x, ref will be %d\n", cache_ref, cache_ref->ref_count+1); - if(cache_ref == NULL) + if (cache_ref == NULL) panic("vm_cache_acquire_ref: passed NULL\n"); - if(acquire_store_ref && cache_ref->cache->store->ops->acquire_ref) { + + if (acquire_store_ref && cache_ref->cache->store->ops->acquire_ref) cache_ref->cache->store->ops->acquire_ref(cache_ref->cache->store); - } + atomic_add(&cache_ref->ref_count, 1); } -void vm_cache_release_ref(vm_cache_ref *cache_ref) + +void +vm_cache_release_ref(vm_cache_ref *cache_ref) { + off_t store_committed_size = 0; vm_page *page; -// dprintf("vm_cache_release_ref: cache_ref 0x%x, ref will be %d\n", cache_ref, cache_ref->ref_count-1); + TRACE(("vm_cache_release_ref: cache_ref 0x%x, ref will be %d\n", cache_ref, cache_ref->ref_count - 1)); - if(cache_ref == NULL) + if (cache_ref == NULL) panic("vm_cache_release_ref: passed NULL\n"); - if(atomic_add(&cache_ref->ref_count, -1) == 1) { - // delete this cache - // delete the cache's backing store, if it has one - off_t store_committed_size = 0; - if(cache_ref->cache->store) { - store_committed_size = cache_ref->cache->store->committed_size; - (*cache_ref->cache->store->ops->destroy)(cache_ref->cache->store); - } - // free all of the pages in the cache - page = cache_ref->cache->page_list; - while(page) { - vm_page *old_page = page; - int state; - - page = page->cache_next; - - // remove it from the hash table - state = disable_interrupts(); - acquire_spinlock(&page_cache_table_lock); - - hash_remove(page_cache_table, old_page); - - release_spinlock(&page_cache_table_lock); - restore_interrupts(state); - -// dprintf("vm_cache_release_ref: freeing page 0x%x\n", old_page->ppn); - vm_page_set_state(old_page, PAGE_STATE_FREE); - } - vm_increase_max_commit(cache_ref->cache->virtual_size - store_committed_size); - - // remove the ref to the source - if(cache_ref->cache->source) - vm_cache_release_ref(cache_ref->cache->source->ref); - - mutex_destroy(&cache_ref->lock); - free(cache_ref->cache); - free(cache_ref); + if (atomic_add(&cache_ref->ref_count, -1) != 1) { + if (cache_ref->cache->store->ops->release_ref) + cache_ref->cache->store->ops->release_ref(cache_ref->cache->store); return; } - if(cache_ref->cache->store->ops->release_ref) { - cache_ref->cache->store->ops->release_ref(cache_ref->cache->store); + + // delete this cache + + // delete the cache's backing store, if it has one + if (cache_ref->cache->store) { + store_committed_size = cache_ref->cache->store->committed_size; + (*cache_ref->cache->store->ops->destroy)(cache_ref->cache->store); } + + // free all of the pages in the cache + page = cache_ref->cache->page_list; + while (page) { + vm_page *oldPage = page; + int state; + + page = page->cache_next; + + // remove it from the hash table + state = disable_interrupts(); + acquire_spinlock(&page_cache_table_lock); + + hash_remove(page_cache_table, oldPage); + + release_spinlock(&page_cache_table_lock); + restore_interrupts(state); + + TRACE(("vm_cache_release_ref: freeing page 0x%x\n", oldPage->ppn)); + vm_page_set_state(oldPage, PAGE_STATE_FREE); + } + vm_increase_max_commit(cache_ref->cache->virtual_size - store_committed_size); + + // remove the ref to the source + if (cache_ref->cache->source) + vm_cache_release_ref(cache_ref->cache->source->ref); + + mutex_destroy(&cache_ref->lock); + free(cache_ref->cache); + free(cache_ref); } -vm_page *vm_cache_lookup_page(vm_cache_ref *cache_ref, off_t offset) + +vm_page * +vm_cache_lookup_page(vm_cache_ref *cache_ref, off_t offset) { vm_page *page; int state; @@ -199,17 +224,19 @@ vm_page *vm_cache_lookup_page(vm_cache_ref *cache_ref, off_t offset) return page; } -void vm_cache_insert_page(vm_cache_ref *cache_ref, vm_page *page, off_t offset) + +void +vm_cache_insert_page(vm_cache_ref *cache_ref, vm_page *page, off_t offset) { int state; -// dprintf("vm_cache_insert_page: cache 0x%x, page 0x%x, offset 0x%x 0x%x\n", cache_ref, page, offset); + TRACE(("vm_cache_insert_page: cache 0x%x, page 0x%x, offset 0x%x 0x%x\n", cache_ref, page, offset)); page->offset = offset; - if(cache_ref->cache->page_list != NULL) { + if (cache_ref->cache->page_list != NULL) cache_ref->cache->page_list->cache_prev = page; - } + page->cache_next = cache_ref->cache->page_list; page->cache_prev = NULL; cache_ref->cache->page_list = page; @@ -226,11 +253,13 @@ void vm_cache_insert_page(vm_cache_ref *cache_ref, vm_page *page, off_t offset) } -void vm_cache_remove_page(vm_cache_ref *cache_ref, vm_page *page) + +void +vm_cache_remove_page(vm_cache_ref *cache_ref, vm_page *page) { int state; -// dprintf("vm_cache_remove_page: cache 0x%x, page 0x%x\n", cache_ref, page); + TRACE(("vm_cache_remove_page: cache 0x%x, page 0x%x\n", cache_ref, page)); state = disable_interrupts(); acquire_spinlock(&page_cache_table_lock); @@ -240,25 +269,27 @@ void vm_cache_remove_page(vm_cache_ref *cache_ref, vm_page *page) release_spinlock(&page_cache_table_lock); restore_interrupts(state); - if(cache_ref->cache->page_list == page) { - if(page->cache_next != NULL) + if (cache_ref->cache->page_list == page) { + if (page->cache_next != NULL) page->cache_next->cache_prev = NULL; cache_ref->cache->page_list = page->cache_next; } else { - if(page->cache_prev != NULL) + if (page->cache_prev != NULL) page->cache_prev->cache_next = page->cache_next; - if(page->cache_next != NULL) + if (page->cache_next != NULL) page->cache_next->cache_prev = page->cache_prev; } page->cache_ref = NULL; } -int vm_cache_insert_region(vm_cache_ref *cache_ref, vm_region *region) + +int +vm_cache_insert_region(vm_cache_ref *cache_ref, vm_region *region) { mutex_lock(&cache_ref->lock); region->cache_next = cache_ref->region_list; - if(region->cache_next) + if (region->cache_next) region->cache_next->cache_prev = region; region->cache_prev = NULL; cache_ref->region_list = region; @@ -267,15 +298,17 @@ int vm_cache_insert_region(vm_cache_ref *cache_ref, vm_region *region) return 0; } -int vm_cache_remove_region(vm_cache_ref *cache_ref, vm_region *region) + +int +vm_cache_remove_region(vm_cache_ref *cache_ref, vm_region *region) { mutex_lock(&cache_ref->lock); - if(region->cache_prev) + if (region->cache_prev) region->cache_prev->cache_next = region->cache_next; - if(region->cache_next) + if (region->cache_next) region->cache_next->cache_prev = region->cache_prev; - if(cache_ref->region_list == region) + if (cache_ref->region_list == region) cache_ref->region_list = region->cache_next; mutex_unlock(&cache_ref->lock);