- object = (vm_object_t) queue_next(&object->objq)) {
- if (vm_object_lock_try(object)) {
- /* Locked. Great. We'll take it. Remove and return. */
- queue_remove(&queue->objq[group], object,
- vm_object_t, objq);
- object->objq.next = 0;
- object->objq.prev = 0;
+ object = (vm_object_t) queue_next(&object->objq),
+ num_objects_skipped++) {
+
+ if (pick_ripe &&
+ ! object->purgeable_when_ripe) {
+ /* we want an object that has a ripe token */
+ continue;
+ }
+
+ object_task_importance = 0;
+ owner = object->vo_purgeable_owner;
+ if (owner) {
+ object_task_importance = task_importance_estimate(owner);
+ }
+ if (object_task_importance < best_object_task_importance) {
+ if (vm_object_lock_try(object)) {
+ if (best_object != VM_OBJECT_NULL) {
+ /* forget about previous best object */
+ vm_object_unlock(best_object);
+ }
+ best_object = object;
+ best_object_task_importance = object_task_importance;
+ best_object_skipped = num_objects_skipped;
+ if (best_object_task_importance == 0) {
+ /* can't get any better: stop looking */
+ break;
+ }
+ }
+ }
+ }
+
+ if (best_object) {
+ /* Locked. Great. We'll take it. Remove and return. */
+// printf("FOUND PURGEABLE object %p skipped %d\n", object, num_objects_skipped);
+
+ /* clear ownership when dequeueing purgeable object */
+ owner = best_object->vo_purgeable_owner;
+ if (owner) {
+ assert(owner->task_volatile_objects > 0);
+ OSAddAtomic(-1, &owner->task_volatile_objects);
+ best_object->vo_purgeable_owner = NULL;
+ }
+
+ queue_remove(&queue->objq[group], best_object,
+ vm_object_t, objq);
+ best_object->purgeable_queue_type = PURGEABLE_Q_TYPE_MAX;
+ best_object->purgeable_queue_group = 0;
+ best_object->objq.next = NULL;
+ best_object->objq.prev = NULL;