diff --git a/vm/vm_object.c b/vm/vm_object.c index 9057973..6d12d4b 100644 --- a/vm/vm_object.c +++ b/vm/vm_object.c @@ -349,6 +349,46 @@ void vm_object_reference( } /* + * vm_object_collect: + * + * Called by the pageout daemon when the system needs more free pages. + */ +void vm_object_collect(void) +{ + vm_object_t object, next, temp; + + vm_object_cache_lock(); + object = (vm_object_t) queue_first(&vm_object_cached_list); + + while (!queue_end(&vm_object_cached_list, (queue_entry_t) object)) { + next = (vm_object_t) queue_next(&object->cached_list); + + if (object->resident_page_count == 0) { + vm_object_lock(object); + if ((object->pager_created && + !object->pager_initialized)) { + /* Not ready, look at it later */ + vm_object_unlock(object); + continue; + } + queue_remove(&vm_object_cached_list, object, + vm_object_t, cached_list); + vm_object_cached_count--; + + assert(object->ref_count == 0); + + temp = object->shadow; + vm_object_terminate(object); + if (temp) { + vm_object_deallocate(temp); + } + } + object = next; + } + vm_object_cache_unlock(); +} + +/* * vm_object_deallocate: * * Release a reference to the specified object, @@ -407,6 +447,7 @@ void vm_object_deallocate( queue_enter(&vm_object_cached_list, object, vm_object_t, cached_list); overflow = (++vm_object_cached_count > vm_object_cached_max); + overflow = 0; vm_object_cache_unlock(); vm_object_deactivate_pages(object); diff --git a/vm/vm_object.h b/vm/vm_object.h index c992570..6fd1852 100644 --- a/vm/vm_object.h +++ b/vm/vm_object.h @@ -172,6 +172,7 @@ extern void vm_object_init(void); extern void vm_object_terminate(vm_object_t); extern vm_object_t vm_object_allocate(vm_size_t); extern void vm_object_reference(vm_object_t); +extern void vm_object_collect(void); extern void vm_object_deallocate(vm_object_t); extern void vm_object_pmap_protect( vm_object_t object, diff --git a/vm/vm_pageout.c b/vm/vm_pageout.c index 7a755bf..1f18644 100644 --- a/vm/vm_pageout.c +++ b/vm/vm_pageout.c @@ -556,6 +556,7 @@ void vm_pageout_scan() consider_task_collect(); consider_thread_collect(); consider_zone_gc(); + vm_object_collect(); for (burst_count = 0;;) { register vm_page_t m;