-static void
-vm_purgeable_volatile_queue_disown(
- purgeable_q_t queue,
- int group,
- task_t task)
-{
- vm_object_t object;
- int collisions;
-
- collisions = 0;
-
-again:
- LCK_MTX_ASSERT(&vm_purgeable_queue_lock, LCK_MTX_ASSERT_OWNED);
-
- for (object = (vm_object_t) queue_first(&queue->objq[group]);
- !queue_end(&queue->objq[group], (queue_entry_t) object);
- object = (vm_object_t) queue_next(&object->objq)) {
-#if MACH_ASSERT
- /*
- * Sanity check: let's scan the entire queues to
- * make sure we don't leave any purgeable objects
- * pointing back at a dead task. If the counters
- * are off, we would fail to assert that they go
- * back to 0 after disowning is done.
- */
-#else /* MACH_ASSERT */
- if (task->task_volatile_objects == 0) {
- /* no more volatile objects owned by "task" */
- break;
- }
-#endif /* MACH_ASSERT */
- if (object->vo_purgeable_owner == task) {
- if (! vm_object_lock_try(object)) {
- lck_mtx_unlock(&vm_purgeable_queue_lock);
- mutex_pause(collisions++);
- lck_mtx_lock(&vm_purgeable_queue_lock);
- goto again;
- }
- assert(object->purgable == VM_PURGABLE_VOLATILE);
- if (object->vo_purgeable_owner == task) {
- vm_purgeable_accounting(object,
- object->purgable,
- TRUE); /* disown */
- assert(object->vo_purgeable_owner == NULL);
- }
- vm_object_unlock(object);
- }
- }
-}
-