]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/vm/vm_shared_memory_server.c
xnu-344.49.tar.gz
[apple/xnu.git] / osfmk / vm / vm_shared_memory_server.c
index 626fb5fb9bb14aca9419c5f107d7bcf17a287ec0..bc3ef97decbf7a7733c1e591c4ac3e5527565009 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@
  */
@@ -29,7 +32,6 @@
 
 #include <ipc/ipc_port.h>
 #include <kern/thread.h>
-#include <mach/shared_memory_server.h>
 #include <kern/zalloc.h>
 #include <mach/kern_return.h>
 #include <mach/vm_inherit.h>
 #include <vm/vm_map.h>
 #include <vm/vm_page.h>
 
+#include <mach/shared_memory_server.h>
+#include <vm/vm_shared_memory_server.h>
+
+/* forward declarations */
+static kern_return_t           
+shared_file_init(               
+        ipc_port_t      *shared_text_region_handle,
+        vm_size_t       text_region_size,
+        ipc_port_t      *shared_data_region_handle,
+        vm_size_t       data_region_size, 
+        vm_offset_t     *shared_file_mapping_array);
+
+static load_struct_t  *
+lsf_hash_lookup(   
+        queue_head_t                   *hash_table,
+        void                           *file_object,  
+        int                            size,
+       boolean_t                       alternate,
+       shared_region_task_mappings_t   sm_info);
+
+static load_struct_t *
+lsf_hash_delete(
+        void                           *file_object,
+       vm_offset_t                     base_offset,
+       shared_region_task_mappings_t   sm_info);
+
+static void    
+lsf_hash_insert(
+        load_struct_t   *entry,
+       shared_region_task_mappings_t   sm_info);
+
+static kern_return_t                   
+lsf_load(
+        vm_offset_t                    mapped_file,
+        vm_size_t                              mapped_file_size,
+        vm_offset_t                            *base_address,
+        sf_mapping_t                           *mappings,
+        int                                    map_cnt,
+        void                                   *file_object,
+        int                            flags,
+       shared_region_task_mappings_t   sm_info);
+
+static void
+lsf_unload(
+        void                           *file_object,
+       vm_offset_t                     base_offset,
+       shared_region_task_mappings_t   sm_info);
+
+
+#define load_file_hash(file_object, size) \
+               ((((natural_t)file_object) & 0xffffff) % size)
 
+/* Implementation */
 vm_offset_t            shared_file_text_region;
 vm_offset_t            shared_file_data_region;
 
 ipc_port_t             shared_text_region_handle;
 ipc_port_t             shared_data_region_handle;
 vm_offset_t            shared_file_mapping_array = 0;
-shared_region_mapping_t        system_shared_region;
+shared_region_mapping_t        system_shared_region = NULL;
 
 ipc_port_t             sfma_handle = NULL;
 zone_t                 lsf_zone;
@@ -84,18 +138,31 @@ shared_file_boot_time_init(
 {
        long                    shared_text_region_size;
        long                    shared_data_region_size;
+       shared_region_mapping_t new_system_region;
+       shared_region_mapping_t old_system_region;
 
        shared_text_region_size = 0x10000000;
        shared_data_region_size = 0x10000000;
        shared_file_init(&shared_text_region_handle,
                shared_text_region_size, &shared_data_region_handle,
                shared_data_region_size, &shared_file_mapping_array);
+       
        shared_region_mapping_create(shared_text_region_handle,
                shared_text_region_size, shared_data_region_handle,
                shared_data_region_size, shared_file_mapping_array,
-               GLOBAL_SHARED_TEXT_SEGMENT, &system_shared_region,
+               GLOBAL_SHARED_TEXT_SEGMENT, &new_system_region,
                0x9000000, 0x9000000);
+       old_system_region = system_shared_region;
+       system_shared_region = new_system_region;
        system_shared_region->flags = SHARED_REGION_SYSTEM;
+        /* consume the reference held because this is the  */
+        /* system shared region */
+       if(old_system_region) {
+                shared_region_mapping_dealloc(old_system_region);
+       }
+       /* hold an extra reference because these are the system */
+       /* shared regions. */
+       shared_region_mapping_ref(system_shared_region);
        vm_set_shared_region(current_task(), system_shared_region);
 
 }
@@ -108,7 +175,7 @@ shared_file_boot_time_init(
 /* but also coordinates requests for space.  */
 
 
-kern_return_t
+static kern_return_t
 shared_file_init(
        ipc_port_t      *shared_text_region_handle,
        vm_size_t       text_region_size, 
@@ -172,7 +239,8 @@ shared_file_init(
                        p->busy = FALSE;
                        vm_object_unlock(buf_object);
                        pmap_enter(kernel_pmap, b, p->phys_addr,
-                               VM_PROT_READ | VM_PROT_WRITE, TRUE);
+                               VM_PROT_READ | VM_PROT_WRITE, 
+                               VM_WIMG_USE_DEFAULT, TRUE);
                }
 
 
@@ -233,10 +301,11 @@ copyin_shared_file(
        vm_offset_t     *base_address, 
        int             map_cnt,
        sf_mapping_t    *mappings,
-       vm_object_t     file_object,
+       memory_object_control_t file_control,
        shared_region_task_mappings_t   sm_info,
        int             *flags)
 {
+       vm_object_t     file_object;
        vm_map_entry_t          entry;
        shared_file_info_t      *shared_file_header;
        load_struct_t           *file_entry;
@@ -301,7 +370,7 @@ copyin_shared_file(
        
        /* Find the entry in the map associated with the current mapping */
        /* of the file object */
-
+       file_object = memory_object_control_to_vm_object(file_control);
        if(vm_map_lookup_entry(current_map(), mapped_file, &entry)) {
                vm_object_t     mapped_object;
                if(entry->is_sub_map) {
@@ -386,9 +455,13 @@ copyin_shared_file(
                        regions = (shared_region_mapping_t)sm_info->self;
                        regions->flags |= SHARED_REGION_FULL;
                        if(regions == system_shared_region) {
+                               shared_region_mapping_t new_system_shared_regions;
                                shared_file_boot_time_init();
-                               /* current task must stay wit its current */
-                               /* regions */
+                               /* current task must stay with its current */
+                               /* regions, drop count on system_shared_region */
+                               /* and put back our original set */
+                               vm_get_shared_region(current_task(), &new_system_shared_regions);
+                               shared_region_mapping_dealloc(new_system_shared_regions);
                                vm_set_shared_region(current_task(), regions);
                        }
                }
@@ -400,7 +473,7 @@ copyin_shared_file(
 /* A hash lookup function for the list of loaded files in      */
 /* shared_memory_server space.  */
 
-load_struct_t  *
+static load_struct_t  *
 lsf_hash_lookup(
        queue_head_t                    *hash_table,
        void                            *file_object,
@@ -485,7 +558,7 @@ lsf_remove_regions_mappings(
 /* Removes a map_list, (list of loaded extents) for a file from     */
 /* the loaded file hash table.  */
 
-load_struct_t *
+static load_struct_t *
 lsf_hash_delete(
        void            *file_object,
        vm_offset_t     base_offset,
@@ -521,7 +594,7 @@ lsf_hash_delete(
 /* Inserts a new map_list, (list of loaded file extents), into the */
 /* server loaded file hash table. */
 
-void
+static void
 lsf_hash_insert(
        load_struct_t                   *entry,
        shared_region_task_mappings_t   sm_info)
@@ -541,7 +614,7 @@ lsf_hash_insert(
 /* if any extent fails to load or if the file was already loaded */
 /* in a different configuration, lsf_load fails.                 */
 
-kern_return_t
+static kern_return_t
 lsf_load(
        vm_offset_t     mapped_file,
        vm_size_t       mapped_file_size,
@@ -707,7 +780,7 @@ lsf_load(
 /* If one is found the associated extents in shared memory are deallocated */
 /* and the extent list is freed */
 
-void
+static void
 lsf_unload(
        void                    *file_object,
        vm_offset_t             base_offset,
@@ -740,3 +813,10 @@ lsf_unload(
                shared_file_available_hash_ele++;
        }
 }
+
+/* integer is from 1 to 100 and represents percent full */
+unsigned int
+lsf_mapping_pool_gauge()
+{
+       return ((lsf_zone->count * lsf_zone->elem_size) * 100)/lsf_zone->max_size;
+}