]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/vm/memory_object.c
xnu-344.21.73.tar.gz
[apple/xnu.git] / osfmk / vm / memory_object.c
index 90de302291f790596ce38ed55e5cb4238ad8a85e..c3e0f22f0feeb67c633cc9dcec68adf2dc5a3357 100644 (file)
@@ -3,19 +3,22 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -132,7 +135,7 @@ vm_object_update(vm_object_t, vm_object_offset_t,
 
 #define        memory_object_should_return_page(m, should_return) \
     (should_return != MEMORY_OBJECT_RETURN_NONE && \
-     (((m)->dirty || ((m)->dirty = pmap_is_modified((m)->phys_addr))) || \
+     (((m)->dirty || ((m)->dirty = pmap_is_modified((m)->phys_page))) || \
       ((m)->precious && (should_return) == MEMORY_OBJECT_RETURN_ALL) || \
       (should_return) == MEMORY_OBJECT_RETURN_ANYTHING))
 
@@ -188,8 +191,19 @@ memory_object_lock_page(
         *      does not have any data.
         */
 
-       if (m->absent || m->error || m->restart)
-               return(MEMORY_OBJECT_LOCK_RESULT_DONE);
+       if (m->absent || m->error || m->restart) {
+               if(m->error && should_flush) {
+                       /* dump the page, pager wants us to */
+                       /* clean it up and there is no      */
+                       /* relevant data to return */
+                       if(m->wire_count == 0) {
+                               VM_PAGE_FREE(m);
+                               return(MEMORY_OBJECT_LOCK_RESULT_DONE);
+                       }
+               } else {
+                       return(MEMORY_OBJECT_LOCK_RESULT_DONE);
+               }
+       }
 
        assert(!m->fictitious);
 
@@ -244,7 +258,7 @@ memory_object_lock_page(
 
        if (prot != VM_PROT_NO_CHANGE) {
                if ((m->page_lock ^ prot) & prot) {
-                       pmap_page_protect(m->phys_addr, VM_PROT_ALL & ~prot);
+                       pmap_page_protect(m->phys_page, VM_PROT_ALL & ~prot);
                }
 #if 0
                /* code associated with the vestigial 
@@ -289,7 +303,7 @@ memory_object_lock_page(
                vm_page_unlock_queues();
 
                if (!should_flush)
-                       pmap_page_protect(m->phys_addr, VM_PROT_NONE);
+                       pmap_page_protect(m->phys_page, VM_PROT_NONE);
 
                if (m->dirty)
                        return(MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN);
@@ -395,7 +409,7 @@ memory_object_lock_request(
        if ((prot & ~VM_PROT_ALL) != 0 && prot != VM_PROT_NO_CHANGE)
                return (KERN_INVALID_ARGUMENT);
 
-       size = round_page(size);
+       size = round_page_64(size);
 
        /*
         *      Lock the object, and acquire a paging reference to
@@ -765,10 +779,7 @@ BYPASS_COW_COPYIN:
                                continue;
                        }
 
-                       PAGE_ASSERT_WAIT(m, THREAD_UNINT);
-                       vm_object_unlock(object);
-                       thread_block((void (*)(void))0);
-                       vm_object_lock(object);
+                       PAGE_SLEEP(object, m, THREAD_UNINT);
                        continue;
 
                    case MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN:
@@ -801,9 +812,7 @@ BYPASS_COW_COPYIN:
                        m->busy = FALSE;
                        holding_page = VM_PAGE_NULL;
                        if(m->cleaning) {
-                               PAGE_ASSERT_WAIT(m, THREAD_UNINT);
-                               vm_object_unlock(object);
-                               thread_block((void (*)(void))0);
+                               PAGE_SLEEP(object, m, THREAD_UNINT);
                                continue;
                        }
                        if(!pending_pageout) {
@@ -954,7 +963,7 @@ vm_object_set_attributes_common(
                temporary = TRUE;
        if (cluster_size != 0) {
                int     pages_per_cluster;
-               pages_per_cluster = atop(cluster_size);
+               pages_per_cluster = atop_32(cluster_size);
                /*
                 * Cluster size must be integral multiple of page size,
                 * and be a power of 2 number of pages.
@@ -1090,7 +1099,7 @@ memory_object_change_attributes(
                 perf = (memory_object_perf_info_t) attributes;
 
                may_cache = perf->may_cache;
-               cluster_size = round_page(perf->cluster_size);
+               cluster_size = round_page_32(perf->cluster_size);
 
                break;
            }
@@ -1415,7 +1424,7 @@ host_default_memory_manager(
                        mutex_unlock(&memory_manager_default_lock);
                        return KERN_INVALID_ARGUMENT;
 #else
-                       cluster_size = round_page(cluster_size);
+                       cluster_size = round_page_32(cluster_size);
 #endif
                }
                memory_manager_default_cluster = cluster_size;
@@ -1451,9 +1460,12 @@ memory_manager_default_reference(
        mutex_lock(&memory_manager_default_lock);
        current_manager = memory_manager_default;
        while (current_manager == MEMORY_OBJECT_DEFAULT_NULL) {
-               thread_sleep_mutex((event_t) &memory_manager_default,
-                       &memory_manager_default_lock, THREAD_UNINT);
-               mutex_lock(&memory_manager_default_lock);
+               wait_result_t res;
+
+               res = thread_sleep_mutex((event_t) &memory_manager_default,
+                                        &memory_manager_default_lock,
+                                        THREAD_UNINT);
+               assert(res == THREAD_AWAKENED);
                current_manager = memory_manager_default;
        }
        memory_object_default_reference(current_manager);
@@ -1539,17 +1551,25 @@ memory_object_deactivate_pages(
                                if ((m->wire_count == 0) && (!m->private) && (!m->gobbled) && (!m->busy)) {
 
                                        m->reference = FALSE;
-                                       pmap_clear_reference(m->phys_addr);
+                                       pmap_clear_reference(m->phys_page);
 
                                        if ((kill_page) && (object->internal)) {
                                                m->precious = FALSE;
                                                m->dirty = FALSE;
-                                               pmap_clear_modify(m->phys_addr);
+                                               pmap_clear_modify(m->phys_page);
                                                vm_external_state_clr(object->existence_map, offset);
                                        }
                                        VM_PAGE_QUEUES_REMOVE(m);
 
-                                       queue_enter_first(&vm_page_queue_inactive, m, vm_page_t, pageq);
+                                       if(m->zero_fill) {
+                                               queue_enter_first(
+                                                       &vm_page_queue_zf, 
+                                                       m, vm_page_t, pageq);
+                                       } else {
+                                               queue_enter_first(
+                                                       &vm_page_queue_inactive, 
+                                                       m, vm_page_t, pageq);
+                                       }
 
                                        m->inactive = TRUE;
                                        if (!m->fictitious)  
@@ -1590,7 +1610,7 @@ memory_object_page_op(
        memory_object_control_t control,
        memory_object_offset_t  offset,
        int                     ops,
-       vm_offset_t             *phys_entry,
+       ppnum_t                 *phys_entry,
        int                     *flags)
 {
        vm_object_t             object;
@@ -1606,8 +1626,8 @@ memory_object_page_op(
        if(ops & UPL_POP_PHYSICAL) {
                if(object->phys_contiguous) {
                        if (phys_entry) {
-                               *phys_entry = (vm_offset_t)
-                                               object->shadow_offset;
+                               *phys_entry = (ppnum_t)
+                                       (object->shadow_offset >> 12);
                        }
                        vm_object_unlock(object);
                        return KERN_SUCCESS;
@@ -1634,10 +1654,7 @@ memory_object_page_op(
                           (ops & UPL_POP_BUSY)) || (ops & UPL_POP_DUMP))) {
                        /* someone else is playing with the page, we will */
                        /* have to wait */
-                       PAGE_ASSERT_WAIT(dst_page, THREAD_UNINT);
-                       vm_object_unlock(object);
-                       thread_block((void(*)(void))0);
-                       vm_object_lock(object);
+                       PAGE_SLEEP(object, dst_page, THREAD_UNINT);
                        continue;
                }
 
@@ -1661,7 +1678,7 @@ memory_object_page_op(
                        if(dst_page->busy) *flags |= UPL_POP_BUSY;
                }
                if (phys_entry)
-                       *phys_entry = dst_page->phys_addr;
+                       *phys_entry = dst_page->phys_page;
        
                /* The caller should have made a call either contingent with */
                /* or prior to this call to set UPL_POP_BUSY */